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