summaryrefslogtreecommitdiffstats
path: root/Doc/library/asyncio-extending.rst
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2022-03-31 21:06:07 (GMT)
committerGitHub <noreply@github.com>2022-03-31 21:06:07 (GMT)
commitab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f (patch)
tree1749d1627947e81219f5b9676c7490a55d389af3 /Doc/library/asyncio-extending.rst
parent4a08c4c469d36f99d3a5e0f17ad82ab35dcf2835 (diff)
downloadcpython-ab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f.zip
cpython-ab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f.tar.gz
cpython-ab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f.tar.bz2
bpo-45099: Document asyncio internal API (GH-32166)
Diffstat (limited to 'Doc/library/asyncio-extending.rst')
-rw-r--r--Doc/library/asyncio-extending.rst93
1 files changed, 93 insertions, 0 deletions
diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst
new file mode 100644
index 0000000..619723e
--- /dev/null
+++ b/Doc/library/asyncio-extending.rst
@@ -0,0 +1,93 @@
+.. currentmodule:: asyncio
+
+
+=========
+Extending
+=========
+
+The main direction for :mod:`asyncio` extending is writing custom *event loop*
+classes. Asyncio has helpers that could be used to simplify this task.
+
+.. note::
+
+ Third-parties should reuse existing asyncio code with caution,
+ a new Python version is free to break backward compatibility
+ in *internal* part of API.
+
+
+Writing a Custom Event Loop
+===========================
+
+:class:`asyncio.AbstractEventLoop` declares very many methods. Implementing all them
+from scratch is a tedious job.
+
+A loop can get many common methods implementation for free by inheriting from
+:class:`asyncio.BaseEventLoop`.
+
+In turn, the successor should implement a bunch of *private* methods declared but not
+implemented in :class:`asyncio.BaseEventLoop`.
+
+For example, ``loop.create_connection()`` checks arguments, resolves DNS addresses, and
+calls ``loop._make_socket_transport()`` that should be implemented by inherited class.
+The ``_make_socket_transport()`` method is not documented and is considered as an
+*internal* API.
+
+
+
+Future and Task private constructors
+====================================
+
+:class:`asyncio.Future` and :class:`asyncio.Task` should be never created directly,
+please use corresponding :meth:`loop.create_future` and :meth:`loop.create_task`,
+or :func:`asyncio.create_task` factories instead.
+
+However, third-party *event loops* may *reuse* built-in future and task implementations
+for the sake of getting a complex and highly optimized code for free.
+
+For this purpose the following, *private* constructors are listed:
+
+.. method:: Future.__init__(*, loop=None)
+
+Create a built-in future instance.
+
+*loop* is an optional event loop instance.
+
+.. method:: Task.__init__(coro, *, loop=None, name=None, context=None)
+
+Create a built-in task instance.
+
+*loop* is an optional event loop instance. The rest of arguments are described in
+:meth:`loop.create_task` description.
+
+
+Task lifetime support
+=====================
+
+A third party task implementation should call the following functions to keep a task
+visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`:
+
+.. function:: _register_task(task)
+
+ Register a new *task* as managed by *asyncio*.
+
+ Call the function from a task constructor.
+
+.. function:: _unregister_task(task)
+
+ Unregister a *task* from *asyncio* internal structures.
+
+ The function should be called when a task is about to finish.
+
+.. function:: _enter_task(loop, task)
+
+ Switch the current task to the *task* argument.
+
+ Call the function just before executing a portion of embedded *coroutine*
+ (:meth:`coroutine.send` or :meth:`coroutine.throw`).
+
+.. function:: _leave_task(loop, task)
+
+ Switch the current task back from *task* to ``None``.
+
+ Call the function just after :meth:`coroutine.send` or :meth:`coroutine.throw`
+ execution.