1.. currentmodule:: asyncio 2 3 4========= 5Extending 6========= 7 8The main direction for :mod:`asyncio` extending is writing custom *event loop* 9classes. Asyncio has helpers that could be used to simplify this task. 10 11.. note:: 12 13 Third-parties should reuse existing asyncio code with caution, 14 a new Python version is free to break backward compatibility 15 in *internal* part of API. 16 17 18Writing a Custom Event Loop 19=========================== 20 21:class:`asyncio.AbstractEventLoop` declares very many methods. Implementing all them 22from scratch is a tedious job. 23 24A loop can get many common methods implementation for free by inheriting from 25:class:`asyncio.BaseEventLoop`. 26 27In turn, the successor should implement a bunch of *private* methods declared but not 28implemented in :class:`asyncio.BaseEventLoop`. 29 30For example, ``loop.create_connection()`` checks arguments, resolves DNS addresses, and 31calls ``loop._make_socket_transport()`` that should be implemented by inherited class. 32The ``_make_socket_transport()`` method is not documented and is considered as an 33*internal* API. 34 35 36 37Future and Task private constructors 38==================================== 39 40:class:`asyncio.Future` and :class:`asyncio.Task` should be never created directly, 41please use corresponding :meth:`loop.create_future` and :meth:`loop.create_task`, 42or :func:`asyncio.create_task` factories instead. 43 44However, third-party *event loops* may *reuse* built-in future and task implementations 45for the sake of getting a complex and highly optimized code for free. 46 47For this purpose the following, *private* constructors are listed: 48 49.. method:: Future.__init__(*, loop=None) 50 51 Create a built-in future instance. 52 53 *loop* is an optional event loop instance. 54 55.. method:: Task.__init__(coro, *, loop=None, name=None, context=None) 56 57 Create a built-in task instance. 58 59 *loop* is an optional event loop instance. The rest of arguments are described in 60 :meth:`loop.create_task` description. 61 62 .. versionchanged:: 3.11 63 64 *context* argument is added. 65 66 67 68Task lifetime support 69===================== 70 71A third party task implementation should call the following functions to keep a task 72visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`: 73 74.. function:: _register_task(task) 75 76 Register a new *task* as managed by *asyncio*. 77 78 Call the function from a task constructor. 79 80.. function:: _unregister_task(task) 81 82 Unregister a *task* from *asyncio* internal structures. 83 84 The function should be called when a task is about to finish. 85 86.. function:: _enter_task(loop, task) 87 88 Switch the current task to the *task* argument. 89 90 Call the function just before executing a portion of embedded *coroutine* 91 (:meth:`coroutine.send` or :meth:`coroutine.throw`). 92 93.. function:: _leave_task(loop, task) 94 95 Switch the current task back from *task* to ``None``. 96 97 Call the function just after :meth:`coroutine.send` or :meth:`coroutine.throw` 98 execution. 99