This method is idempotent and irreversible. No other methods
should be called after the event loop is closed.
-.. coroutinemethod:: loop.shutdown_asyncgens()
+.. method:: loop.shutdown_asyncgens()
+ :async:
Schedule all currently open :term:`asynchronous generator` objects to
close with an :meth:`~agen.aclose` call. After calling this method,
.. versionadded:: 3.6
-.. coroutinemethod:: loop.shutdown_default_executor(timeout=None)
+.. method:: loop.shutdown_default_executor(timeout=None)
+ :async:
Schedule the closure of the default executor and wait for it to join all of
the threads in the :class:`~concurrent.futures.ThreadPoolExecutor`.
Opening network connections
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. coroutinemethod:: loop.create_connection(protocol_factory, \
- host=None, port=None, *, ssl=None, \
- family=0, proto=0, flags=0, sock=None, \
- local_addr=None, server_hostname=None, \
- ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, \
- happy_eyeballs_delay=None, interleave=None, \
- all_errors=False)
+.. method:: loop.create_connection(protocol_factory, \
+ host=None, port=None, *, ssl=None, \
+ family=0, proto=0, flags=0, sock=None, \
+ local_addr=None, server_hostname=None, \
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, \
+ happy_eyeballs_delay=None, interleave=None, \
+ all_errors=False)
+ :async:
Open a streaming transport connection to a given
address specified by *host* and *port*.
API. It returns a pair of (:class:`StreamReader`, :class:`StreamWriter`)
that can be used directly in async/await code.
-.. coroutinemethod:: loop.create_datagram_endpoint(protocol_factory, \
- local_addr=None, remote_addr=None, *, \
- family=0, proto=0, flags=0, \
- reuse_port=None, \
- allow_broadcast=None, sock=None)
+.. method:: loop.create_datagram_endpoint(protocol_factory, \
+ local_addr=None, remote_addr=None, *, \
+ family=0, proto=0, flags=0, \
+ reuse_port=None, \
+ allow_broadcast=None, sock=None)
+ :async:
Create a datagram connection.
The *reuse_address* parameter, disabled since Python 3.8.1,
3.7.6 and 3.6.10, has been entirely removed.
-.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
- path=None, *, ssl=None, sock=None, \
- server_hostname=None, ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None)
+.. method:: loop.create_unix_connection(protocol_factory, \
+ path=None, *, ssl=None, sock=None, \
+ server_hostname=None, ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None)
+ :async:
Create a Unix connection.
.. _loop_create_server:
-.. coroutinemethod:: loop.create_server(protocol_factory, \
- host=None, port=None, *, \
- family=socket.AF_UNSPEC, \
- flags=socket.AI_PASSIVE, \
- sock=None, backlog=100, ssl=None, \
- reuse_address=None, reuse_port=None, \
- keep_alive=None, \
- ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, \
- start_serving=True)
+.. method:: loop.create_server(protocol_factory, \
+ host=None, port=None, *, \
+ family=socket.AF_UNSPEC, \
+ flags=socket.AI_PASSIVE, \
+ sock=None, backlog=100, ssl=None, \
+ reuse_address=None, reuse_port=None, \
+ keep_alive=None, \
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, \
+ start_serving=True)
+ :async:
Create a TCP server (socket type :const:`~socket.SOCK_STREAM`) listening
on *port* of the *host* address.
that can be used in an async/await code.
-.. coroutinemethod:: loop.create_unix_server(protocol_factory, path=None, \
- *, sock=None, backlog=100, ssl=None, \
- ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, \
- start_serving=True, cleanup_socket=True)
+.. method:: loop.create_unix_server(protocol_factory, path=None, \
+ *, sock=None, backlog=100, ssl=None, \
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, \
+ start_serving=True, cleanup_socket=True)
+ :async:
Similar to :meth:`loop.create_server` but works with the
:py:const:`~socket.AF_UNIX` socket family.
Added the *cleanup_socket* parameter.
-.. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \
- sock, *, ssl=None, ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None)
+.. method:: loop.connect_accepted_socket(protocol_factory, \
+ sock, *, ssl=None, ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None)
+ :async:
Wrap an already accepted connection into a transport/protocol pair.
Transferring files
^^^^^^^^^^^^^^^^^^
-.. coroutinemethod:: loop.sendfile(transport, file, \
- offset=0, count=None, *, fallback=True)
+.. method:: loop.sendfile(transport, file, \
+ offset=0, count=None, *, fallback=True)
+ :async:
Send a *file* over a *transport*. Return the total number of bytes
sent.
TLS Upgrade
^^^^^^^^^^^
-.. coroutinemethod:: loop.start_tls(transport, protocol, \
- sslcontext, *, server_side=False, \
- server_hostname=None, ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None)
+.. method:: loop.start_tls(transport, protocol, \
+ sslcontext, *, server_side=False, \
+ server_hostname=None, ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None)
+ :async:
Upgrade an existing transport-based connection to TLS.
working with :class:`~socket.socket` objects directly is more
convenient.
-.. coroutinemethod:: loop.sock_recv(sock, nbytes)
+.. method:: loop.sock_recv(sock, nbytes)
+ :async:
Receive up to *nbytes* from *sock*. Asynchronous version of
:meth:`socket.recv() <socket.socket.recv>`.
method, releases before Python 3.7 returned a :class:`Future`.
Since Python 3.7 this is an ``async def`` method.
-.. coroutinemethod:: loop.sock_recv_into(sock, buf)
+.. method:: loop.sock_recv_into(sock, buf)
+ :async:
Receive data from *sock* into the *buf* buffer. Modeled after the blocking
:meth:`socket.recv_into() <socket.socket.recv_into>` method.
.. versionadded:: 3.7
-.. coroutinemethod:: loop.sock_recvfrom(sock, bufsize)
+.. method:: loop.sock_recvfrom(sock, bufsize)
+ :async:
Receive a datagram of up to *bufsize* from *sock*. Asynchronous version of
:meth:`socket.recvfrom() <socket.socket.recvfrom>`.
.. versionadded:: 3.11
-.. coroutinemethod:: loop.sock_recvfrom_into(sock, buf, nbytes=0)
+.. method:: loop.sock_recvfrom_into(sock, buf, nbytes=0)
+ :async:
Receive a datagram of up to *nbytes* from *sock* into *buf*.
Asynchronous version of
.. versionadded:: 3.11
-.. coroutinemethod:: loop.sock_sendall(sock, data)
+.. method:: loop.sock_sendall(sock, data)
+ :async:
Send *data* to the *sock* socket. Asynchronous version of
:meth:`socket.sendall() <socket.socket.sendall>`.
method, before Python 3.7 it returned a :class:`Future`.
Since Python 3.7, this is an ``async def`` method.
-.. coroutinemethod:: loop.sock_sendto(sock, data, address)
+.. method:: loop.sock_sendto(sock, data, address)
+ :async:
Send a datagram from *sock* to *address*.
Asynchronous version of
.. versionadded:: 3.11
-.. coroutinemethod:: loop.sock_connect(sock, address)
+.. method:: loop.sock_connect(sock, address)
+ :async:
Connect *sock* to a remote socket at *address*.
and :func:`asyncio.open_connection() <open_connection>`.
-.. coroutinemethod:: loop.sock_accept(sock)
+.. method:: loop.sock_accept(sock)
+ :async:
Accept a connection. Modeled after the blocking
:meth:`socket.accept() <socket.socket.accept>` method.
:meth:`loop.create_server` and :func:`start_server`.
-.. coroutinemethod:: loop.sock_sendfile(sock, file, offset=0, count=None, \
- *, fallback=True)
+.. method:: loop.sock_sendfile(sock, file, offset=0, count=None, \
+ *, fallback=True)
+ :async:
Send a file using high-performance :mod:`os.sendfile` if possible.
Return the total number of bytes sent.
DNS
^^^
-.. coroutinemethod:: loop.getaddrinfo(host, port, *, family=0, \
- type=0, proto=0, flags=0)
+.. method:: loop.getaddrinfo(host, port, *, family=0, \
+ type=0, proto=0, flags=0)
+ :async:
Asynchronous version of :meth:`socket.getaddrinfo`.
-.. coroutinemethod:: loop.getnameinfo(sockaddr, flags=0)
+.. method:: loop.getnameinfo(sockaddr, flags=0)
+ :async:
Asynchronous version of :meth:`socket.getnameinfo`.
Working with pipes
^^^^^^^^^^^^^^^^^^
-.. coroutinemethod:: loop.connect_read_pipe(protocol_factory, pipe)
+.. method:: loop.connect_read_pipe(protocol_factory, pipe)
+ :async:
Register the read end of *pipe* in the event loop.
With :class:`SelectorEventLoop` event loop, the *pipe* is set to
non-blocking mode.
-.. coroutinemethod:: loop.connect_write_pipe(protocol_factory, pipe)
+.. method:: loop.connect_write_pipe(protocol_factory, pipe)
+ :async:
Register the write end of *pipe* in the event loop.
.. _loop_subprocess_exec:
-.. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, **kwargs)
+.. method:: loop.subprocess_exec(protocol_factory, *args, \
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
+ stderr=subprocess.PIPE, **kwargs)
+ :async:
Create a subprocess from one or more string arguments specified by
*args*.
conforms to the :class:`asyncio.SubprocessTransport` base class and
*protocol* is an object instantiated by the *protocol_factory*.
-.. coroutinemethod:: loop.subprocess_shell(protocol_factory, cmd, *, \
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, **kwargs)
+.. method:: loop.subprocess_shell(protocol_factory, cmd, *, \
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
+ stderr=subprocess.PIPE, **kwargs)
+ :async:
Create a subprocess from *cmd*, which can be a :class:`str` or a
:class:`bytes` string encoded to the
.. versionadded:: 3.7
- .. coroutinemethod:: start_serving()
+ .. method:: start_serving()
+ :async:
Start accepting connections.
.. versionadded:: 3.7
- .. coroutinemethod:: serve_forever()
+ .. method:: serve_forever()
+ :async:
Start accepting connections until the coroutine is cancelled.
Cancellation of ``serve_forever`` task causes the server
.. versionadded:: 3.7
- .. coroutinemethod:: wait_closed()
+ .. method:: wait_closed()
+ :async:
Wait until the :meth:`close` method completes and all active
connections have finished.
If the queue was initialized with ``maxsize=0`` (the default),
then :meth:`full` never returns ``True``.
- .. coroutinemethod:: get()
+ .. method:: get()
+ :async:
Remove and return an item from the queue. If queue is empty,
wait until an item is available.
Return an item if one is immediately available, else raise
:exc:`QueueEmpty`.
- .. coroutinemethod:: join()
+ .. method:: join()
+ :async:
Block until all items in the queue have been received and processed.
work on it is complete. When the count of unfinished tasks drops
to zero, :meth:`join` unblocks.
- .. coroutinemethod:: put(item)
+ .. method:: put(item)
+ :async:
Put an item into the queue. If the queue is full, wait until a
free slot is available before adding the item.
and work with streams:
-.. coroutinefunction:: open_connection(host=None, port=None, *, \
- limit=None, ssl=None, family=0, proto=0, \
- flags=0, sock=None, local_addr=None, \
- server_hostname=None, ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, \
- happy_eyeballs_delay=None, interleave=None)
+.. function:: open_connection(host=None, port=None, *, \
+ limit=None, ssl=None, family=0, proto=0, \
+ flags=0, sock=None, local_addr=None, \
+ server_hostname=None, ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, \
+ happy_eyeballs_delay=None, interleave=None)
+ :async:
Establish a network connection and return a pair of
``(reader, writer)`` objects.
Added the *ssl_shutdown_timeout* parameter.
-.. coroutinefunction:: start_server(client_connected_cb, host=None, \
- port=None, *, limit=None, \
- family=socket.AF_UNSPEC, \
- flags=socket.AI_PASSIVE, sock=None, \
- backlog=100, ssl=None, reuse_address=None, \
- reuse_port=None, keep_alive=None, \
- ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, start_serving=True)
+.. function:: start_server(client_connected_cb, host=None, \
+ port=None, *, limit=None, \
+ family=socket.AF_UNSPEC, \
+ flags=socket.AI_PASSIVE, sock=None, \
+ backlog=100, ssl=None, reuse_address=None, \
+ reuse_port=None, keep_alive=None, \
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, start_serving=True)
+ :async:
Start a socket server.
.. rubric:: Unix Sockets
-.. coroutinefunction:: open_unix_connection(path=None, *, limit=None, \
- ssl=None, sock=None, server_hostname=None, \
- ssl_handshake_timeout=None, ssl_shutdown_timeout=None)
+.. function:: open_unix_connection(path=None, *, limit=None, \
+ ssl=None, sock=None, server_hostname=None, \
+ ssl_handshake_timeout=None, ssl_shutdown_timeout=None)
+ :async:
Establish a Unix socket connection and return a pair of
``(reader, writer)``.
Added the *ssl_shutdown_timeout* parameter.
-.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \
- *, limit=None, sock=None, backlog=100, ssl=None, \
- ssl_handshake_timeout=None, \
- ssl_shutdown_timeout=None, start_serving=True)
+.. function:: start_unix_server(client_connected_cb, path=None, \
+ *, limit=None, sock=None, backlog=100, ssl=None, \
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, start_serving=True)
+ :async:
Start a Unix socket server.
Acknowledge the EOF.
- .. coroutinemethod:: read(n=-1)
+ .. method:: read(n=-1)
+ :async:
Read up to *n* bytes from the stream.
If EOF is received before any byte is read, return an empty
``bytes`` object.
- .. coroutinemethod:: readline()
+ .. method:: readline()
+ :async:
Read one line, where "line" is a sequence of bytes
ending with ``\n``.
If EOF is received and the internal buffer is empty,
return an empty ``bytes`` object.
- .. coroutinemethod:: readexactly(n)
+ .. method:: readexactly(n)
+ :async:
Read exactly *n* bytes.
can be read. Use the :attr:`IncompleteReadError.partial`
attribute to get the partially read data.
- .. coroutinemethod:: readuntil(separator=b'\n')
+ .. method:: readuntil(separator=b'\n')
+ :async:
Read data from the stream until *separator* is found.
Access optional transport information; see
:meth:`BaseTransport.get_extra_info` for details.
- .. coroutinemethod:: drain()
+ .. method:: drain()
+ :async:
Wait until it is appropriate to resume writing to the stream.
Example::
be resumed. When there is nothing to wait for, the :meth:`drain`
returns immediately.
- .. coroutinemethod:: start_tls(sslcontext, *, server_hostname=None, \
- ssl_handshake_timeout=None, ssl_shutdown_timeout=None)
+ .. method:: start_tls(sslcontext, *, server_hostname=None, \
+ ssl_handshake_timeout=None, ssl_shutdown_timeout=None)
+ :async:
Upgrade an existing stream-based connection to TLS.
.. versionadded:: 3.7
- .. coroutinemethod:: wait_closed()
+ .. method:: wait_closed()
+ :async:
Wait until the stream is closed.
Creating Subprocesses
=====================
-.. coroutinefunction:: create_subprocess_exec(program, *args, stdin=None, \
- stdout=None, stderr=None, limit=None, **kwds)
+.. function:: create_subprocess_exec(program, *args, stdin=None, \
+ stdout=None, stderr=None, limit=None, **kwds)
+ :async:
Create a subprocess.
Removed the *loop* parameter.
-.. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \
- stdout=None, stderr=None, limit=None, **kwds)
+.. function:: create_subprocess_shell(cmd, stdin=None, \
+ stdout=None, stderr=None, limit=None, **kwds)
+ :async:
Run the *cmd* shell command.
See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>`
section.
- .. coroutinemethod:: wait()
+ .. method:: wait()
+ :async:
Wait for the child process to terminate.
more data. Use the :meth:`communicate` method when using pipes
to avoid this condition.
- .. coroutinemethod:: communicate(input=None)
+ .. method:: communicate(input=None)
+ :async:
Interact with process:
.. versionchanged:: 3.12
- *stdin* gets closed when `input=None` too.
+ *stdin* gets closed when ``input=None`` too.
.. method:: send_signal(signal)
.. versionchanged:: 3.10
Removed the *loop* parameter.
- .. coroutinemethod:: acquire()
+ .. method:: acquire()
+ :async:
Acquire the lock.
asyncio.run(main())
- .. coroutinemethod:: wait()
+ .. method:: wait()
+ :async:
Wait until the event is set.
finally:
cond.release()
- .. coroutinemethod:: acquire()
+ .. method:: acquire()
+ :async:
Acquire the underlying lock.
When invoked on an unlocked lock, a :exc:`RuntimeError` is
raised.
- .. coroutinemethod:: wait()
+ .. method:: wait()
+ :async:
Wait until notified.
and be prepared to :meth:`~Condition.wait` again. For this reason, you may
prefer to use :meth:`~Condition.wait_for` instead.
- .. coroutinemethod:: wait_for(predicate)
+ .. method:: wait_for(predicate)
+ :async:
Wait until a predicate becomes *true*.
finally:
sem.release()
- .. coroutinemethod:: acquire()
+ .. method:: acquire()
+ :async:
Acquire a semaphore.
.. versionadded:: 3.11
- .. coroutinemethod:: wait()
+ .. method:: wait()
+ :async:
Pass the barrier. When all the tasks party to the barrier have called
this function, they are all unblocked simultaneously.
barrier is broken or reset while a task is waiting.
It could raise a :exc:`CancelledError` if a task is cancelled.
- .. coroutinemethod:: reset()
+ .. method:: reset()
+ :async:
Return the barrier to the default, empty state. Any tasks waiting on it
will receive the :class:`BrokenBarrierError` exception.
If a barrier is broken it may be better to just leave it and create a new one.
- .. coroutinemethod:: abort()
+ .. method:: abort()
+ :async:
Put the barrier into a broken state. This causes any active or future
calls to :meth:`~Barrier.wait` to fail with the :class:`BrokenBarrierError`.
Sleeping
========
-.. coroutinefunction:: sleep(delay, result=None)
+.. function:: sleep(delay, result=None)
+ :async:
Block for *delay* seconds.
.. versionadded:: 3.11
-.. coroutinefunction:: wait_for(aw, timeout)
+.. function:: wait_for(aw, timeout)
+ :async:
Wait for the *aw* :ref:`awaitable <asyncio-awaitables>`
to complete with a timeout.
Waiting Primitives
==================
-.. coroutinefunction:: wait(aws, *, timeout=None, return_when=ALL_COMPLETED)
+.. function:: wait(aws, *, timeout=None, return_when=ALL_COMPLETED)
+ :async:
Run :class:`~asyncio.Future` and :class:`~asyncio.Task` instances in the *aws*
iterable concurrently and block until the condition specified
Running in Threads
==================
-.. coroutinefunction:: to_thread(func, /, *args, **kwargs)
+.. function:: to_thread(func, /, *args, **kwargs)
+ :async:
Asynchronously run function *func* in a separate thread.
The :meth:`~ExitStack.close` method is not implemented; :meth:`aclose` must be used
instead.
- .. coroutinemethod:: enter_async_context(cm)
+ .. method:: enter_async_context(cm)
+ :async:
Similar to :meth:`ExitStack.enter_context` but expects an asynchronous context
manager.
Similar to :meth:`ExitStack.callback` but expects a coroutine function.
- .. coroutinemethod:: aclose()
+ .. method:: aclose()
+ :async:
Similar to :meth:`ExitStack.close` but properly handles awaitables.
.. versionadded:: 3.13
- .. coroutinemethod:: asyncSetUp()
+ .. method:: asyncSetUp()
+ :async:
Method called to prepare the test fixture. This is called after :meth:`setUp`.
This is called immediately before calling the test method; other than
will be considered an error rather than a test failure. The default implementation
does nothing.
- .. coroutinemethod:: asyncTearDown()
+ .. method:: asyncTearDown()
+ :async:
Method called immediately after the test method has been called and the
result recorded. This is called before :meth:`tearDown`. This is called even if
This method accepts a coroutine that can be used as a cleanup function.
- .. coroutinemethod:: enterAsyncContext(cm)
+ .. method:: enterAsyncContext(cm)
+ :async:
Enter the supplied :term:`asynchronous context manager`. If successful,
also add its :meth:`~object.__aexit__` method as a cleanup function by
.. index:: pair: exception; StopAsyncIteration
-.. coroutinemethod:: agen.__anext__()
+.. method:: agen.__anext__()
+ :async:
Returns an awaitable which when run starts to execute the asynchronous
generator or resumes it at the last executed yield expression. When an
This method is normally called implicitly by a :keyword:`async for` loop.
-.. coroutinemethod:: agen.asend(value)
+.. method:: agen.asend(value)
+ :async:
Returns an awaitable which when run resumes the execution of the
asynchronous generator. As with the :meth:`~generator.send` method for a
because there is no yield expression that could receive the value.
-.. coroutinemethod:: agen.athrow(value)
- agen.athrow(type[, value[, traceback]])
+.. method:: agen.athrow(value)
+ agen.athrow(type[, value[, traceback]])
+ :async:
Returns an awaitable that raises an exception of type ``type`` at the point
where the asynchronous generator was paused, and returns the next value
.. index:: pair: exception; GeneratorExit
-.. coroutinemethod:: agen.aclose()
+.. method:: agen.aclose()
+ :async:
Returns an awaitable that when run will throw a :exc:`GeneratorExit` into
the asynchronous generator function at the point where it was paused.
return [refnode], []
-class PyCoroutineMixin(object):
- def handle_signature(self, sig, signode):
- ret = super(PyCoroutineMixin, self).handle_signature(sig, signode)
- signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine '))
- return ret
-
-
class PyAwaitableMixin(object):
def handle_signature(self, sig, signode):
ret = super(PyAwaitableMixin, self).handle_signature(sig, signode)
return ret
-class PyCoroutineFunction(PyCoroutineMixin, PyFunction):
- def run(self):
- self.name = 'py:function'
- return PyFunction.run(self)
-
-
-class PyCoroutineMethod(PyCoroutineMixin, PyMethod):
- def run(self):
- self.name = 'py:method'
- return PyMethod.run(self)
-
-
class PyAwaitableFunction(PyAwaitableMixin, PyFunction):
def run(self):
self.name = 'py:function'
app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature)
app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command)
app.add_object_type('monitoring-event', 'monitoring-event', '%s (monitoring event)', parse_monitoring_event)
- app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction)
- app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod)
app.add_directive_to_domain('py', 'awaitablefunction', PyAwaitableFunction)
app.add_directive_to_domain('py', 'awaitablemethod', PyAwaitableMethod)
app.connect('env-check-consistency', patch_pairindextypes)