summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2018-08-08 21:06:47 (GMT)
committerYury Selivanov <yury@magic.io>2018-08-08 21:06:47 (GMT)
commitcca4eec3c0a67cbfeaf09182ea6c097a94891ff6 (patch)
tree0d04ad10797fa95e5e09f8b32e8aa9e0c50f6aac
parent52dee687af3671a31f63d6432de0d9ef370fd7b0 (diff)
downloadcpython-cca4eec3c0a67cbfeaf09182ea6c097a94891ff6.zip
cpython-cca4eec3c0a67cbfeaf09182ea6c097a94891ff6.tar.gz
cpython-cca4eec3c0a67cbfeaf09182ea6c097a94891ff6.tar.bz2
bpo-34270: Make it possible to name asyncio tasks (GH-8547)
Co-authored-by: Antti Haapala <antti.haapala@anttipatterns.com>
-rw-r--r--Doc/library/asyncio-eventloop.rst8
-rw-r--r--Doc/library/asyncio-task.rst36
-rw-r--r--Doc/whatsnew/3.8.rst7
-rw-r--r--Lib/asyncio/base_events.py6
-rw-r--r--Lib/asyncio/base_tasks.py6
-rw-r--r--Lib/asyncio/events.py2
-rw-r--r--Lib/asyncio/tasks.py35
-rw-r--r--Lib/test/test_asyncio/test_base_events.py28
-rw-r--r--Lib/test/test_asyncio/test_tasks.py55
-rw-r--r--Misc/ACKS2
-rw-r--r--Misc/NEWS.d/next/Library/2018-07-29-11-32-56.bpo-34270.aL6P-3.rst8
-rw-r--r--Modules/_asynciomodule.c60
-rw-r--r--Modules/clinic/_asynciomodule.c.h41
13 files changed, 266 insertions, 28 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 5b3d29d..1006853 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -246,7 +246,7 @@ Futures
Tasks
-----
-.. method:: AbstractEventLoop.create_task(coro)
+.. method:: AbstractEventLoop.create_task(coro, \*, name=None)
Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in
a future. Return a :class:`Task` object.
@@ -255,8 +255,14 @@ Tasks
interoperability. In this case, the result type is a subclass of
:class:`Task`.
+ If the *name* argument is provided and not ``None``, it is set as the name
+ of the task using :meth:`Task.set_name`.
+
.. versionadded:: 3.4.2
+ .. versionchanged:: 3.8
+ Added the ``name`` parameter.
+
.. method:: AbstractEventLoop.set_task_factory(factory)
Set a task factory that will be used by
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 2b480d4..c73f36b 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -387,10 +387,13 @@ with the result.
Task
----
-.. function:: create_task(coro)
+.. function:: create_task(coro, \*, name=None)
Wrap a :ref:`coroutine <coroutine>` *coro* into a task and schedule
- its execution. Return the task object.
+ its execution. Return the task object.
+
+ If *name* is not ``None``, it is set as the name of the task using
+ :meth:`Task.set_name`.
The task is executed in :func:`get_running_loop` context,
:exc:`RuntimeError` is raised if there is no running loop in
@@ -398,7 +401,10 @@ Task
.. versionadded:: 3.7
-.. class:: Task(coro, \*, loop=None)
+ .. versionchanged:: 3.8
+ Added the ``name`` parameter.
+
+.. class:: Task(coro, \*, loop=None, name=None)
A unit for concurrent running of :ref:`coroutines <coroutine>`,
subclass of :class:`Future`.
@@ -438,6 +444,9 @@ Task
.. versionchanged:: 3.7
Added support for the :mod:`contextvars` module.
+ .. versionchanged:: 3.8
+ Added the ``name`` parameter.
+
.. classmethod:: all_tasks(loop=None)
Return a set of all tasks for an event loop.
@@ -504,6 +513,27 @@ Task
get_stack(). The file argument is an I/O stream to which the output
is written; by default output is written to sys.stderr.
+ .. method:: get_name()
+
+ Return the name of the task.
+
+ If no name has been explicitly assigned to the task, the default
+ ``Task`` implementation generates a default name during instantiation.
+
+ .. versionadded:: 3.8
+
+ .. method:: set_name(value)
+
+ Set the name of the task.
+
+ The *value* argument can be any object, which is then converted to a
+ string.
+
+ In the default ``Task`` implementation, the name will be visible in the
+ :func:`repr` output of a task object.
+
+ .. versionadded:: 3.8
+
Example: Parallel execution of tasks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index bab1e06..6e0c8b8 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -249,6 +249,13 @@ Changes in the Python API
* ``PyGC_Head`` struct is changed completely. All code touched the
struct member should be rewritten. (See :issue:`33597`)
+* Asyncio tasks can now be named, either by passing the ``name`` keyword
+ argument to :func:`asyncio.create_task` or
+ the :meth:`~asyncio.AbstractEventLoop.create_task` event loop method, or by
+ calling the :meth:`~asyncio.Task.set_name` method on the task object. The
+ task name is visible in the ``repr()`` output of :class:`asyncio.Task` and
+ can also be retrieved using the :meth:`~asyncio.Task.get_name` method.
+
CPython bytecode changes
------------------------
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 78fe2a7..ee13d1a 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -384,18 +384,20 @@ class BaseEventLoop(events.AbstractEventLoop):
"""Create a Future object attached to the loop."""
return futures.Future(loop=self)
- def create_task(self, coro):
+ def create_task(self, coro, *, name=None):
"""Schedule a coroutine object.
Return a task object.
"""
self._check_closed()
if self._task_factory is None:
- task = tasks.Task(coro, loop=self)
+ task = tasks.Task(coro, loop=self, name=name)
if task._source_traceback:
del task._source_traceback[-1]
else:
task = self._task_factory(self, coro)
+ tasks._set_task_name(task, name)
+
return task
def set_task_factory(self, factory):
diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py
index 3ce51f6..e2da462 100644
--- a/Lib/asyncio/base_tasks.py
+++ b/Lib/asyncio/base_tasks.py
@@ -12,11 +12,13 @@ def _task_repr_info(task):
# replace status
info[0] = 'cancelling'
+ info.insert(1, 'name=%r' % task.get_name())
+
coro = coroutines._format_coroutine(task._coro)
- info.insert(1, f'coro=<{coro}>')
+ info.insert(2, f'coro=<{coro}>')
if task._fut_waiter is not None:
- info.insert(2, f'wait_for={task._fut_waiter!r}')
+ info.insert(3, f'wait_for={task._fut_waiter!r}')
return info
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index e4e6322..58a60a0 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -277,7 +277,7 @@ class AbstractEventLoop:
# Method scheduling a coroutine object: create a task.
- def create_task(self, coro):
+ def create_task(self, coro, *, name=None):
raise NotImplementedError
# Methods for interacting with threads.
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 72792a2..03d71d3 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -13,6 +13,7 @@ import concurrent.futures
import contextvars
import functools
import inspect
+import itertools
import types
import warnings
import weakref
@@ -23,6 +24,11 @@ from . import events
from . import futures
from .coroutines import coroutine
+# Helper to generate new task names
+# This uses itertools.count() instead of a "+= 1" operation because the latter
+# is not thread safe. See bpo-11866 for a longer explanation.
+_task_name_counter = itertools.count(1).__next__
+
def current_task(loop=None):
"""Return a currently executed task."""
@@ -48,6 +54,16 @@ def _all_tasks_compat(loop=None):
return {t for t in _all_tasks if futures._get_loop(t) is loop}
+def _set_task_name(task, name):
+ if name is not None:
+ try:
+ set_name = task.set_name
+ except AttributeError:
+ pass
+ else:
+ set_name(name)
+
+
class Task(futures._PyFuture): # Inherit Python Task implementation
# from a Python Future implementation.
@@ -94,7 +110,7 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
stacklevel=2)
return _all_tasks_compat(loop)
- def __init__(self, coro, *, loop=None):
+ def __init__(self, coro, *, loop=None, name=None):
super().__init__(loop=loop)
if self._source_traceback:
del self._source_traceback[-1]
@@ -104,6 +120,11 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
self._log_destroy_pending = False
raise TypeError(f"a coroutine was expected, got {coro!r}")
+ if name is None:
+ self._name = f'Task-{_task_name_counter()}'
+ else:
+ self._name = str(name)
+
self._must_cancel = False
self._fut_waiter = None
self._coro = coro
@@ -126,6 +147,12 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
def _repr_info(self):
return base_tasks._task_repr_info(self)
+ def get_name(self):
+ return self._name
+
+ def set_name(self, value):
+ self._name = str(value)
+
def set_result(self, result):
raise RuntimeError('Task does not support set_result operation')
@@ -312,13 +339,15 @@ else:
Task = _CTask = _asyncio.Task
-def create_task(coro):
+def create_task(coro, *, name=None):
"""Schedule the execution of a coroutine object in a spawn task.
Return a Task object.
"""
loop = events.get_running_loop()
- return loop.create_task(coro)
+ task = loop.create_task(coro)
+ _set_task_name(task, name)
+ return task
# wait() and as_completed() similar to those in PEP 3148.
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index f3ae140..e108637 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -825,6 +825,34 @@ class BaseEventLoopTests(test_utils.TestCase):
task._log_destroy_pending = False
coro.close()
+ def test_create_named_task_with_default_factory(self):
+ async def test():
+ pass
+
+ loop = asyncio.new_event_loop()
+ task = loop.create_task(test(), name='test_task')
+ try:
+ self.assertEqual(task.get_name(), 'test_task')
+ finally:
+ loop.run_until_complete(task)
+ loop.close()
+
+ def test_create_named_task_with_custom_factory(self):
+ def task_factory(loop, coro):
+ return asyncio.Task(coro, loop=loop)
+
+ async def test():
+ pass
+
+ loop = asyncio.new_event_loop()
+ loop.set_task_factory(task_factory)
+ task = loop.create_task(test(), name='test_task')
+ try:
+ self.assertEqual(task.get_name(), 'test_task')
+ finally:
+ loop.run_until_complete(task)
+ loop.close()
+
def test_run_forever_keyboard_interrupt(self):
# Python issue #22601: ensure that the temporary task created by
# run_forever() consumes the KeyboardInterrupt and so don't log
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index a5442f5..c930593 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -87,8 +87,8 @@ class BaseTaskTests:
Task = None
Future = None
- def new_task(self, loop, coro):
- return self.__class__.Task(coro, loop=loop)
+ def new_task(self, loop, coro, name='TestTask'):
+ return self.__class__.Task(coro, loop=loop, name=name)
def new_future(self, loop):
return self.__class__.Future(loop=loop)
@@ -295,12 +295,12 @@ class BaseTaskTests:
coro = format_coroutine(coro_qualname, 'running', src,
t._source_traceback, generator=True)
self.assertEqual(repr(t),
- '<Task pending %s cb=[<Dummy>()]>' % coro)
+ "<Task pending name='TestTask' %s cb=[<Dummy>()]>" % coro)
# test cancelling Task
t.cancel() # Does not take immediate effect!
self.assertEqual(repr(t),
- '<Task cancelling %s cb=[<Dummy>()]>' % coro)
+ "<Task cancelling name='TestTask' %s cb=[<Dummy>()]>" % coro)
# test cancelled Task
self.assertRaises(asyncio.CancelledError,
@@ -308,7 +308,7 @@ class BaseTaskTests:
coro = format_coroutine(coro_qualname, 'done', src,
t._source_traceback)
self.assertEqual(repr(t),
- '<Task cancelled %s>' % coro)
+ "<Task cancelled name='TestTask' %s>" % coro)
# test finished Task
t = self.new_task(self.loop, notmuch())
@@ -316,7 +316,36 @@ class BaseTaskTests:
coro = format_coroutine(coro_qualname, 'done', src,
t._source_traceback)
self.assertEqual(repr(t),
- "<Task finished %s result='abc'>" % coro)
+ "<Task finished name='TestTask' %s result='abc'>" % coro)
+
+ def test_task_repr_autogenerated(self):
+ @asyncio.coroutine
+ def notmuch():
+ return 123
+
+ t1 = self.new_task(self.loop, notmuch(), None)
+ t2 = self.new_task(self.loop, notmuch(), None)
+ self.assertNotEqual(repr(t1), repr(t2))
+
+ match1 = re.match("^<Task pending name='Task-(\d+)'", repr(t1))
+ self.assertIsNotNone(match1)
+ match2 = re.match("^<Task pending name='Task-(\d+)'", repr(t2))
+ self.assertIsNotNone(match2)
+
+ # Autogenerated task names should have monotonically increasing numbers
+ self.assertLess(int(match1.group(1)), int(match2.group(1)))
+ self.loop.run_until_complete(t1)
+ self.loop.run_until_complete(t2)
+
+ def test_task_repr_name_not_str(self):
+ @asyncio.coroutine
+ def notmuch():
+ return 123
+
+ t = self.new_task(self.loop, notmuch())
+ t.set_name({6})
+ self.assertEqual(t.get_name(), '{6}')
+ self.loop.run_until_complete(t)
def test_task_repr_coro_decorator(self):
self.loop.set_debug(False)
@@ -376,7 +405,7 @@ class BaseTaskTests:
t._source_traceback,
generator=not coroutines._DEBUG)
self.assertEqual(repr(t),
- '<Task pending %s cb=[<Dummy>()]>' % coro)
+ "<Task pending name='TestTask' %s cb=[<Dummy>()]>" % coro)
self.loop.run_until_complete(t)
def test_task_repr_wait_for(self):
@@ -2260,6 +2289,18 @@ class BaseTaskTests:
self.loop.run_until_complete(coro())
+ def test_bare_create_named_task(self):
+
+ async def coro_noop():
+ pass
+
+ async def coro():
+ task = asyncio.create_task(coro_noop(), name='No-op')
+ self.assertEqual(task.get_name(), 'No-op')
+ await task
+
+ self.loop.run_until_complete(coro())
+
def test_context_1(self):
cvar = contextvars.ContextVar('cvar', default='nope')
diff --git a/Misc/ACKS b/Misc/ACKS
index 0cb73a0..8c8d954 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -573,6 +573,7 @@ Elliot Gorokhovsky
Hans de Graaff
Tim Graham
Kim Gräsman
+Alex Grönholm
Nathaniel Gray
Eddy De Greef
Duane Griffin
@@ -594,6 +595,7 @@ Michael Guravage
Lars Gustäbel
Thomas Güttler
Jonas H.
+Antti Haapala
Joseph Hackman
Barry Haddow
Philipp Hagemeister
diff --git a/Misc/NEWS.d/next/Library/2018-07-29-11-32-56.bpo-34270.aL6P-3.rst b/Misc/NEWS.d/next/Library/2018-07-29-11-32-56.bpo-34270.aL6P-3.rst
new file mode 100644
index 0000000..a66e110
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-07-29-11-32-56.bpo-34270.aL6P-3.rst
@@ -0,0 +1,8 @@
+The default asyncio task class now always has a name which can be get or set
+using two new methods (:meth:`~asyncio.Task.get_name()` and
+:meth:`~asyncio.Task.set_name`) and is visible in the :func:`repr` output. An
+initial name can also be set using the new ``name`` keyword argument to
+:func:`asyncio.create_task` or the
+:meth:`~asyncio.AbstractEventLoop.create_task` method of the event loop.
+If no initial name is set, the default Task implementation generates a name
+like ``Task-1`` using a monotonic counter.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index ebda104..3c94848 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -37,6 +37,8 @@ static PyObject *context_kwname;
static PyObject *cached_running_holder;
static volatile uint64_t cached_running_holder_tsid;
+/* Counter for autogenerated Task names */
+static uint64_t task_name_counter = 0;
/* WeakSet containing all alive tasks. */
static PyObject *all_tasks;
@@ -78,6 +80,7 @@ typedef struct {
FutureObj_HEAD(task)
PyObject *task_fut_waiter;
PyObject *task_coro;
+ PyObject *task_name;
PyContext *task_context;
int task_must_cancel;
int task_log_destroy_pending;
@@ -1934,13 +1937,15 @@ _asyncio.Task.__init__
coro: object
*
loop: object = None
+ name: object = None
A coroutine wrapped in a Future.
[clinic start generated code]*/
static int
-_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
-/*[clinic end generated code: output=9f24774c2287fc2f input=8d132974b049593e]*/
+_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
+ PyObject *name)
+/*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/
{
if (future_init((FutureObj*)self, loop)) {
return -1;
@@ -1969,6 +1974,18 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
Py_INCREF(coro);
Py_XSETREF(self->task_coro, coro);
+ if (name == Py_None) {
+ name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter);
+ } else if (!PyUnicode_Check(name)) {
+ name = PyObject_Str(name);
+ } else {
+ Py_INCREF(name);
+ }
+ Py_XSETREF(self->task_name, name);
+ if (self->task_name == NULL) {
+ return -1;
+ }
+
if (task_call_step_soon(self, NULL)) {
return -1;
}
@@ -1981,6 +1998,7 @@ TaskObj_clear(TaskObj *task)
(void)FutureObj_clear((FutureObj*) task);
Py_CLEAR(task->task_context);
Py_CLEAR(task->task_coro);
+ Py_CLEAR(task->task_name);
Py_CLEAR(task->task_fut_waiter);
return 0;
}
@@ -1990,6 +2008,7 @@ TaskObj_traverse(TaskObj *task, visitproc visit, void *arg)
{
Py_VISIT(task->task_context);
Py_VISIT(task->task_coro);
+ Py_VISIT(task->task_name);
Py_VISIT(task->task_fut_waiter);
(void)FutureObj_traverse((FutureObj*) task, visit, arg);
return 0;
@@ -2297,6 +2316,41 @@ _asyncio_Task_set_exception(TaskObj *self, PyObject *exception)
return NULL;
}
+/*[clinic input]
+_asyncio.Task.get_name
+[clinic start generated code]*/
+
+static PyObject *
+_asyncio_Task_get_name_impl(TaskObj *self)
+/*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/
+{
+ if (self->task_name) {
+ Py_INCREF(self->task_name);
+ return self->task_name;
+ }
+
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+_asyncio.Task.set_name
+
+ value: object
+ /
+[clinic start generated code]*/
+
+static PyObject *
+_asyncio_Task_set_name(TaskObj *self, PyObject *value)
+/*[clinic end generated code: output=138a8d51e32057d6 input=a8359b6e65f8fd31]*/
+{
+ PyObject *name = PyObject_Str(value);
+ if (name == NULL) {
+ return NULL;
+ }
+
+ Py_XSETREF(self->task_name, name);
+ Py_RETURN_NONE;
+}
static void
TaskObj_finalize(TaskObj *task)
@@ -2382,6 +2436,8 @@ static PyMethodDef TaskType_methods[] = {
_ASYNCIO_TASK_GET_STACK_METHODDEF
_ASYNCIO_TASK_PRINT_STACK_METHODDEF
_ASYNCIO_TASK__REPR_INFO_METHODDEF
+ _ASYNCIO_TASK_GET_NAME_METHODDEF
+ _ASYNCIO_TASK_SET_NAME_METHODDEF
{NULL, NULL} /* Sentinel */
};
diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h
index d8e1b6a..4f5326f 100644
--- a/Modules/clinic/_asynciomodule.c.h
+++ b/Modules/clinic/_asynciomodule.c.h
@@ -253,28 +253,30 @@ _asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored))
}
PyDoc_STRVAR(_asyncio_Task___init____doc__,
-"Task(coro, *, loop=None)\n"
+"Task(coro, *, loop=None, name=None)\n"
"--\n"
"\n"
"A coroutine wrapped in a Future.");
static int
-_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop);
+_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
+ PyObject *name);
static int
_asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs)
{
int return_value = -1;
- static const char * const _keywords[] = {"coro", "loop", NULL};
- static _PyArg_Parser _parser = {"O|$O:Task", _keywords, 0};
+ static const char * const _keywords[] = {"coro", "loop", "name", NULL};
+ static _PyArg_Parser _parser = {"O|$OO:Task", _keywords, 0};
PyObject *coro;
PyObject *loop = Py_None;
+ PyObject *name = Py_None;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
- &coro, &loop)) {
+ &coro, &loop, &name)) {
goto exit;
}
- return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop);
+ return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name);
exit:
return return_value;
@@ -500,6 +502,31 @@ PyDoc_STRVAR(_asyncio_Task_set_exception__doc__,
#define _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF \
{"set_exception", (PyCFunction)_asyncio_Task_set_exception, METH_O, _asyncio_Task_set_exception__doc__},
+PyDoc_STRVAR(_asyncio_Task_get_name__doc__,
+"get_name($self, /)\n"
+"--\n"
+"\n");
+
+#define _ASYNCIO_TASK_GET_NAME_METHODDEF \
+ {"get_name", (PyCFunction)_asyncio_Task_get_name, METH_NOARGS, _asyncio_Task_get_name__doc__},
+
+static PyObject *
+_asyncio_Task_get_name_impl(TaskObj *self);
+
+static PyObject *
+_asyncio_Task_get_name(TaskObj *self, PyObject *Py_UNUSED(ignored))
+{
+ return _asyncio_Task_get_name_impl(self);
+}
+
+PyDoc_STRVAR(_asyncio_Task_set_name__doc__,
+"set_name($self, value, /)\n"
+"--\n"
+"\n");
+
+#define _ASYNCIO_TASK_SET_NAME_METHODDEF \
+ {"set_name", (PyCFunction)_asyncio_Task_set_name, METH_O, _asyncio_Task_set_name__doc__},
+
PyDoc_STRVAR(_asyncio__get_running_loop__doc__,
"_get_running_loop($module, /)\n"
"--\n"
@@ -711,4 +738,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
exit:
return return_value;
}
-/*[clinic end generated code: output=b6148b0134e7a819 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=67da879c9f841505 input=a9049054013a1b77]*/