FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-100344: Provide C implementation for asyncio.current_task by itamaro · Pull Request #100345 · python/cpython · GitHub

/ cpython Public
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .h  (1) .py  (2) .rst  (2) All 4 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.12.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ asyncio
a custom event loop factory.
(Contributed by Kumar Aditya in :gh:`99388`.)

* Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup.
(Contributed by Itamar Ostricher and Pranav Thulasiram Bhat in :gh:`100344`.)

inspect
-------

Expand Down
5 changes: 4 additions & 1 deletion Lib/asyncio/tasks.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ def _unregister_task(task):
_all_tasks.discard(task)


_py_current_task = current_task
_py_register_task = _register_task
_py_unregister_task = _unregister_task
_py_enter_task = _enter_task
Expand All @@ -973,10 +974,12 @@ def _unregister_task(task):
try:
from _asyncio import (_register_task, _unregister_task,
_enter_task, _leave_task,
_all_tasks, _current_tasks)
_all_tasks, _current_tasks,
current_task)
except ImportError:
pass
else:
_c_current_task = current_task
_c_register_task = _register_task
_c_unregister_task = _unregister_task
_c_enter_task = _enter_task
Expand Down
21 changes: 14 additions & 7 deletions Lib/test/test_asyncio/test_tasks.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2804,6 +2804,7 @@ class CIntrospectionTests(test_utils.TestCase, BaseTaskIntrospectionTests):


class BaseCurrentLoopTests:
current_task = None

def setUp(self):
super().setUp()
Expand All @@ -2814,33 +2815,39 @@ def new_task(self, coro):
raise NotImplementedError

def test_current_task_no_running_loop(self):
self.assertIsNone(asyncio.current_task(loop=self.loop))
self.assertIsNone(self.current_task(loop=self.loop))

def test_current_task_no_running_loop_implicit(self):
with self.assertRaisesRegex(RuntimeError, 'no running event loop'):
asyncio.current_task()
self.current_task()

def test_current_task_with_implicit_loop(self):
async def coro():
self.assertIs(asyncio.current_task(loop=self.loop), task)
self.assertIs(self.current_task(loop=self.loop), task)

self.assertIs(asyncio.current_task(None), task)
self.assertIs(asyncio.current_task(), task)
self.assertIs(self.current_task(None), task)
self.assertIs(self.current_task(), task)

task = self.new_task(coro())
self.loop.run_until_complete(task)
self.assertIsNone(asyncio.current_task(loop=self.loop))
self.assertIsNone(self.current_task(loop=self.loop))


class PyCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase):
current_task = staticmethod(tasks._py_current_task)

def new_task(self, coro):
return tasks._PyTask(coro, loop=self.loop)


@unittest.skipUnless(hasattr(tasks, '_CTask'),
@unittest.skipUnless(hasattr(tasks, '_CTask') and
hasattr(tasks, '_c_current_task'),
'requires the C _asyncio module')
class CCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase):
if hasattr(tasks, '_c_current_task'):
current_task = staticmethod(tasks._c_current_task)
else:
current_task = None

def new_task(self, coro):
return getattr(tasks, '_CTask')(coro, loop=self.loop)
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Provide C implementation for :func:`asyncio.current_task` for a 4x-6x
speedup.
39 changes: 39 additions & 0 deletions Modules/_asynciomodule.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -3314,6 +3314,44 @@ _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task)
}


/*[clinic input]
_asyncio.current_task

loop: object = None

Return a currently executed task.

[clinic start generated code]*/

static PyObject *
_asyncio_current_task_impl(PyObject *module, PyObject *loop)
/*[clinic end generated code: output=fe15ac331a7f981a input=58910f61a5627112]*/
{
PyObject *ret;
asyncio_state *state = get_asyncio_state(module);

if (loop == Py_None) {
loop = _asyncio_get_running_loop_impl(module);
if (loop == NULL) {
return NULL;
}
} else {
Py_INCREF(loop);
}

ret = PyDict_GetItemWithError(state->current_tasks, loop);
Py_DECREF(loop);
if (ret == NULL && PyErr_Occurred()) {
return NULL;
}
else if (ret == NULL) {
Py_RETURN_NONE;
}
Py_INCREF(ret);
return ret;
}


/*********************** Module **************************/


Expand Down Expand Up @@ -3494,6 +3532,7 @@ module_init(asyncio_state *state)
PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");

static PyMethodDef asyncio_methods[] = {
_ASYNCIO_CURRENT_TASK_METHODDEF
_ASYNCIO_GET_EVENT_LOOP_METHODDEF
_ASYNCIO_GET_RUNNING_LOOP_METHODDEF
_ASYNCIO__GET_RUNNING_LOOP_METHODDEF
Expand Down
62 changes: 61 additions & 1 deletion Modules/clinic/_asynciomodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.


Back | FazBrowse Home | New Git URL