Top

neovim.msgpack_rpc.event_loop.asyncio module

Event loop implementation that uses the asyncio standard module.

The asyncio module was added to python standard library on 3.4, and it provides a pure python implementation of an event loop library. It is used as a fallback in case pyuv is not available(on python implementations other than CPython).

Earlier python versions are supported through the trollius package, which is a backport of asyncio that works on Python 2.6+.

"""Event loop implementation that uses the `asyncio` standard module.

The `asyncio` module was added to python standard library on 3.4, and it
provides a pure python implementation of an event loop library. It is used
as a fallback in case pyuv is not available(on python implementations other
than CPython).

Earlier python versions are supported through the `trollius` package, which
is a backport of `asyncio` that works on Python 2.6+.
"""
from __future__ import absolute_import

import os
import sys
from collections import deque

try:
    # For python 3.4+, use the standard library module
    import asyncio
except (ImportError, SyntaxError):
    # Fallback to trollius
    import trollius as asyncio

from .base import BaseEventLoop


loop_cls = asyncio.SelectorEventLoop
if os.name == 'nt':
    # On windows use ProactorEventLoop which support pipes and is backed by the
    # more powerful IOCP facility
    loop_cls = asyncio.ProactorEventLoop


class AsyncioEventLoop(BaseEventLoop, asyncio.Protocol,
                       asyncio.SubprocessProtocol):

    """`BaseEventLoop` subclass that uses `asyncio` as a backend."""

    def connection_made(self, transport):
        """Used to signal `asyncio.Protocol` of a successful connection."""
        self._transport = transport
        if isinstance(transport, asyncio.SubprocessTransport):
            self._transport = transport.get_pipe_transport(0)

    def connection_lost(self, exc):
        """Used to signal `asyncio.Protocol` of a lost connection."""
        self._on_error(exc.args[0] if exc else 'EOF')

    def data_received(self, data):
        """Used to signal `asyncio.Protocol` of incoming data."""
        if self._on_data:
            self._on_data(data)
            return
        self._queued_data.append(data)

    def pipe_connection_lost(self, fd, exc):
        """Used to signal `asyncio.SubprocessProtocol` of a lost connection."""
        self._on_error(exc.args[0] if exc else 'EOF')

    def pipe_data_received(self, fd, data):
        """Used to signal `asyncio.SubprocessProtocol` of incoming data."""
        if fd == 2:  # stderr fd number
            self._on_stderr(data)
        elif self._on_data:
            self._on_data(data)
        else:
            self._queued_data.append(data)

    def process_exited(self):
        """Used to signal `asyncio.SubprocessProtocol` when the child exits."""
        self._on_error('EOF')

    def _init(self):
        self._loop = loop_cls()
        self._queued_data = deque()
        self._fact = lambda: self

    def _connect_tcp(self, address, port):
        coroutine = self._loop.create_connection(self._fact, address, port)
        self._loop.run_until_complete(coroutine)

    def _connect_socket(self, path):
        if os.name == 'nt':
            coroutine = self._loop.create_pipe_connection(self._fact, path)
        else:
            coroutine = self._loop.create_unix_connection(self._fact, path)
        self._loop.run_until_complete(coroutine)

    def _connect_stdio(self):
        coroutine = self._loop.connect_read_pipe(self._fact, sys.stdin)
        self._loop.run_until_complete(coroutine)
        coroutine = self._loop.connect_write_pipe(self._fact, sys.stdout)
        self._loop.run_until_complete(coroutine)

    def _connect_child(self, argv):
        self._child_watcher = asyncio.get_child_watcher()
        self._child_watcher.attach_loop(self._loop)
        coroutine = self._loop.subprocess_exec(self._fact, *argv)
        self._loop.run_until_complete(coroutine)

    def _start_reading(self):
        pass

    def _send(self, data):
        self._transport.write(data)

    def _run(self):
        while self._queued_data:
            self._on_data(self._queued_data.popleft())
        self._loop.run_forever()

    def _stop(self):
        self._loop.stop()

    def _threadsafe_call(self, fn):
        self._loop.call_soon_threadsafe(fn)

    def _setup_signals(self, signals):
        if os.name == 'nt':
            # add_signal_handler is not supported in win32
            self._signals = []
            return

        self._signals = list(signals)
        for signum in self._signals:
            self._loop.add_signal_handler(signum, self._on_signal, signum)

    def _teardown_signals(self):
        for signum in self._signals:
            self._loop.remove_signal_handler(signum)

Classes

class AsyncioEventLoop

BaseEventLoop subclass that uses asyncio as a backend.

class AsyncioEventLoop(BaseEventLoop, asyncio.Protocol,
                       asyncio.SubprocessProtocol):

    """`BaseEventLoop` subclass that uses `asyncio` as a backend."""

    def connection_made(self, transport):
        """Used to signal `asyncio.Protocol` of a successful connection."""
        self._transport = transport
        if isinstance(transport, asyncio.SubprocessTransport):
            self._transport = transport.get_pipe_transport(0)

    def connection_lost(self, exc):
        """Used to signal `asyncio.Protocol` of a lost connection."""
        self._on_error(exc.args[0] if exc else 'EOF')

    def data_received(self, data):
        """Used to signal `asyncio.Protocol` of incoming data."""
        if self._on_data:
            self._on_data(data)
            return
        self._queued_data.append(data)

    def pipe_connection_lost(self, fd, exc):
        """Used to signal `asyncio.SubprocessProtocol` of a lost connection."""
        self._on_error(exc.args[0] if exc else 'EOF')

    def pipe_data_received(self, fd, data):
        """Used to signal `asyncio.SubprocessProtocol` of incoming data."""
        if fd == 2:  # stderr fd number
            self._on_stderr(data)
        elif self._on_data:
            self._on_data(data)
        else:
            self._queued_data.append(data)

    def process_exited(self):
        """Used to signal `asyncio.SubprocessProtocol` when the child exits."""
        self._on_error('EOF')

    def _init(self):
        self._loop = loop_cls()
        self._queued_data = deque()
        self._fact = lambda: self

    def _connect_tcp(self, address, port):
        coroutine = self._loop.create_connection(self._fact, address, port)
        self._loop.run_until_complete(coroutine)

    def _connect_socket(self, path):
        if os.name == 'nt':
            coroutine = self._loop.create_pipe_connection(self._fact, path)
        else:
            coroutine = self._loop.create_unix_connection(self._fact, path)
        self._loop.run_until_complete(coroutine)

    def _connect_stdio(self):
        coroutine = self._loop.connect_read_pipe(self._fact, sys.stdin)
        self._loop.run_until_complete(coroutine)
        coroutine = self._loop.connect_write_pipe(self._fact, sys.stdout)
        self._loop.run_until_complete(coroutine)

    def _connect_child(self, argv):
        self._child_watcher = asyncio.get_child_watcher()
        self._child_watcher.attach_loop(self._loop)
        coroutine = self._loop.subprocess_exec(self._fact, *argv)
        self._loop.run_until_complete(coroutine)

    def _start_reading(self):
        pass

    def _send(self, data):
        self._transport.write(data)

    def _run(self):
        while self._queued_data:
            self._on_data(self._queued_data.popleft())
        self._loop.run_forever()

    def _stop(self):
        self._loop.stop()

    def _threadsafe_call(self, fn):
        self._loop.call_soon_threadsafe(fn)

    def _setup_signals(self, signals):
        if os.name == 'nt':
            # add_signal_handler is not supported in win32
            self._signals = []
            return

        self._signals = list(signals)
        for signum in self._signals:
            self._loop.add_signal_handler(signum, self._on_signal, signum)

    def _teardown_signals(self):
        for signum in self._signals:
            self._loop.remove_signal_handler(signum)

Ancestors (in MRO)

  • AsyncioEventLoop
  • neovim.msgpack_rpc.event_loop.base.BaseEventLoop
  • asyncio.protocols.Protocol
  • asyncio.protocols.SubprocessProtocol
  • asyncio.protocols.BaseProtocol
  • builtins.object

Static methods

def __init__(

self, transport_type, *args)

Initialize and connect the event loop instance.

The only arguments are the transport type and transport-specific configuration, like this:

BaseEventLoop('tcp', '127.0.0.1', 7450) Traceback (most recent call last): ... AttributeError: 'BaseEventLoop' object has no attribute '_init' BaseEventLoop('socket', '/tmp/nvim-socket') Traceback (most recent call last): ... AttributeError: 'BaseEventLoop' object has no attribute '_init' BaseEventLoop('stdio') Traceback (most recent call last): ... AttributeError: 'BaseEventLoop' object has no attribute '_init' BaseEventLoop('child', ['nvim', '--embed', '-u', 'NONE']) Traceback (most recent call last): ... AttributeError: 'BaseEventLoop' object has no attribute '_init'

This calls the implementation-specific initialization _init, one of the _connect_* methods(based on transport_type) and _start_reading()

def __init__(self, transport_type, *args):
    """Initialize and connect the event loop instance.
    The only arguments are the transport type and transport-specific
    configuration, like this:
    >>> BaseEventLoop('tcp', '127.0.0.1', 7450)
    Traceback (most recent call last):
        ...
    AttributeError: 'BaseEventLoop' object has no attribute '_init'
    >>> BaseEventLoop('socket', '/tmp/nvim-socket')
    Traceback (most recent call last):
        ...
    AttributeError: 'BaseEventLoop' object has no attribute '_init'
    >>> BaseEventLoop('stdio')
    Traceback (most recent call last):
        ...
    AttributeError: 'BaseEventLoop' object has no attribute '_init'
    >>> BaseEventLoop('child', ['nvim', '--embed', '-u', 'NONE'])
    Traceback (most recent call last):
        ...
    AttributeError: 'BaseEventLoop' object has no attribute '_init'
    This calls the implementation-specific initialization
    `_init`, one of the `_connect_*` methods(based on `transport_type`)
    and `_start_reading()`
    """
    self._transport_type = transport_type
    self._signames = dict((k, v) for v, k in signal.__dict__.items()
                          if v.startswith('SIG'))
    self._on_data = None
    self._error = None
    self._init()
    getattr(self, '_connect_{}'.format(transport_type))(*args)
    self._start_reading()

def connect_child(

self, argv)

Connect a new Nvim instance. Delegated to _connect_child.

def connect_child(self, argv):
    """Connect a new Nvim instance. Delegated to `_connect_child`."""
    info('Spawning a new nvim instance')
    self._connect_child(argv)

def connect_socket(

self, path)

Connect to socket at path. Delegated to _connect_socket.

def connect_socket(self, path):
    """Connect to socket at `path`. Delegated to `_connect_socket`."""
    info('Connecting to %s', path)
    self._connect_socket(path)

def connect_stdio(

self)

Connect using stdin/stdout. Delegated to _connect_stdio.

def connect_stdio(self):
    """Connect using stdin/stdout. Delegated to `_connect_stdio`."""
    info('Preparing stdin/stdout for streaming data')
    self._connect_stdio()

def connect_tcp(

self, address, port)

Connect to tcp/ip address:port. Delegated to _connect_tcp.

def connect_tcp(self, address, port):
    """Connect to tcp/ip `address`:`port`. Delegated to `_connect_tcp`."""
    info('Connecting to TCP address: %s:%d', address, port)
    self._connect_tcp(address, port)

def connection_lost(

self, exc)

Used to signal asyncio.Protocol of a lost connection.

def connection_lost(self, exc):
    """Used to signal `asyncio.Protocol` of a lost connection."""
    self._on_error(exc.args[0] if exc else 'EOF')

def connection_made(

self, transport)

Used to signal asyncio.Protocol of a successful connection.

def connection_made(self, transport):
    """Used to signal `asyncio.Protocol` of a successful connection."""
    self._transport = transport
    if isinstance(transport, asyncio.SubprocessTransport):
        self._transport = transport.get_pipe_transport(0)

def data_received(

self, data)

Used to signal asyncio.Protocol of incoming data.

def data_received(self, data):
    """Used to signal `asyncio.Protocol` of incoming data."""
    if self._on_data:
        self._on_data(data)
        return
    self._queued_data.append(data)

def eof_received(

self)

Called when the other end calls write_eof() or equivalent.

If this returns a false value (including None), the transport will close itself. If it returns a true value, closing the transport is up to the protocol.

def eof_received(self):
    """Called when the other end calls write_eof() or equivalent.
    If this returns a false value (including None), the transport
    will close itself.  If it returns a true value, closing the
    transport is up to the protocol.
    """

def pause_writing(

self)

Called when the transport's buffer goes over the high-water mark.

Pause and resume calls are paired -- pause_writing() is called once when the buffer goes strictly over the high-water mark (even if subsequent writes increases the buffer size even more), and eventually resume_writing() is called once when the buffer size reaches the low-water mark.

Note that if the buffer size equals the high-water mark, pause_writing() is not called -- it must go strictly over. Conversely, resume_writing() is called when the buffer size is equal or lower than the low-water mark. These end conditions are important to ensure that things go as expected when either mark is zero.

NOTE: This is the only Protocol callback that is not called through EventLoop.call_soon() -- if it were, it would have no effect when it's most needed (when the app keeps writing without yielding until pause_writing() is called).

def pause_writing(self):
    """Called when the transport's buffer goes over the high-water mark.
    Pause and resume calls are paired -- pause_writing() is called
    once when the buffer goes strictly over the high-water mark
    (even if subsequent writes increases the buffer size even
    more), and eventually resume_writing() is called once when the
    buffer size reaches the low-water mark.
    Note that if the buffer size equals the high-water mark,
    pause_writing() is not called -- it must go strictly over.
    Conversely, resume_writing() is called when the buffer size is
    equal or lower than the low-water mark.  These end conditions
    are important to ensure that things go as expected when either
    mark is zero.
    NOTE: This is the only Protocol callback that is not called
    through EventLoop.call_soon() -- if it were, it would have no
    effect when it's most needed (when the app keeps writing
    without yielding until pause_writing() is called).
    """

def pipe_connection_lost(

self, fd, exc)

Used to signal asyncio.SubprocessProtocol of a lost connection.

def pipe_connection_lost(self, fd, exc):
    """Used to signal `asyncio.SubprocessProtocol` of a lost connection."""
    self._on_error(exc.args[0] if exc else 'EOF')

def pipe_data_received(

self, fd, data)

Used to signal asyncio.SubprocessProtocol of incoming data.

def pipe_data_received(self, fd, data):
    """Used to signal `asyncio.SubprocessProtocol` of incoming data."""
    if fd == 2:  # stderr fd number
        self._on_stderr(data)
    elif self._on_data:
        self._on_data(data)
    else:
        self._queued_data.append(data)

def process_exited(

self)

Used to signal asyncio.SubprocessProtocol when the child exits.

def process_exited(self):
    """Used to signal `asyncio.SubprocessProtocol` when the child exits."""
    self._on_error('EOF')

def resume_writing(

self)

Called when the transport's buffer drains below the low-water mark.

See pause_writing() for details.

def resume_writing(self):
    """Called when the transport's buffer drains below the low-water mark.
    See pause_writing() for details.
    """

def run(

self, data_cb)

Run the event loop.

def run(self, data_cb):
    """Run the event loop."""
    if self._error:
        err = self._error
        if isinstance(self._error, KeyboardInterrupt):
            # KeyboardInterrupt is not destructive(it may be used in
            # the REPL).
            # After throwing KeyboardInterrupt, cleanup the _error field
            # so the loop may be started again
            self._error = None
        raise err
    self._on_data = data_cb
    if threading.current_thread() == main_thread:
        self._setup_signals([signal.SIGINT, signal.SIGTERM])
    debug('Entering event loop')
    self._run()
    debug('Exited event loop')
    if threading.current_thread() == main_thread:
        self._teardown_signals()
        signal.signal(signal.SIGINT, default_int_handler)
    self._on_data = None

def send(

self, data)

Queue data for sending to Nvim.

def send(self, data):
    """Queue `data` for sending to Nvim."""
    debug("Sending '%s'", data)
    self._send(data)

def stop(

self)

Stop the event loop.

def stop(self):
    """Stop the event loop."""
    self._stop()
    debug('Stopped event loop')

def threadsafe_call(

self, fn)

Call a function in the event loop thread.

This is the only safe way to interact with a session from other threads.

def threadsafe_call(self, fn):
    """Call a function in the event loop thread.
    This is the only safe way to interact with a session from other
    threads.
    """
    self._threadsafe_call(fn)

class loop_cls

Unix event loop.

Adds signal handling and UNIX Domain Socket support to SelectorEventLoop.

class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
    """Unix event loop.

    Adds signal handling and UNIX Domain Socket support to SelectorEventLoop.
    """

    def __init__(self, selector=None):
        super().__init__(selector)
        self._signal_handlers = {}

    def _socketpair(self):
        return socket.socketpair()

    def close(self):
        super().close()
        for sig in list(self._signal_handlers):
            self.remove_signal_handler(sig)

    def _process_self_data(self, data):
        for signum in data:
            if not signum:
                # ignore null bytes written by _write_to_self()
                continue
            self._handle_signal(signum)

    def add_signal_handler(self, sig, callback, *args):
        """Add a handler for a signal.  UNIX only.

        Raise ValueError if the signal number is invalid or uncatchable.
        Raise RuntimeError if there is a problem setting up the handler.
        """
        if (coroutines.iscoroutine(callback)
        or coroutines.iscoroutinefunction(callback)):
            raise TypeError("coroutines cannot be used "
                            "with add_signal_handler()")
        self._check_signal(sig)
        self._check_closed()
        try:
            # set_wakeup_fd() raises ValueError if this is not the
            # main thread.  By calling it early we ensure that an
            # event loop running in another thread cannot add a signal
            # handler.
            signal.set_wakeup_fd(self._csock.fileno())
        except (ValueError, OSError) as exc:
            raise RuntimeError(str(exc))

        handle = events.Handle(callback, args, self)
        self._signal_handlers[sig] = handle

        try:
            # Register a dummy signal handler to ask Python to write the signal
            # number in the wakup file descriptor. _process_self_data() will
            # read signal numbers from this file descriptor to handle signals.
            signal.signal(sig, _sighandler_noop)

            # Set SA_RESTART to limit EINTR occurrences.
            signal.siginterrupt(sig, False)
        except OSError as exc:
            del self._signal_handlers[sig]
            if not self._signal_handlers:
                try:
                    signal.set_wakeup_fd(-1)
                except (ValueError, OSError) as nexc:
                    logger.info('set_wakeup_fd(-1) failed: %s', nexc)

            if exc.errno == errno.EINVAL:
                raise RuntimeError('sig {} cannot be caught'.format(sig))
            else:
                raise

    def _handle_signal(self, sig):
        """Internal helper that is the actual signal handler."""
        handle = self._signal_handlers.get(sig)
        if handle is None:
            return  # Assume it's some race condition.
        if handle._cancelled:
            self.remove_signal_handler(sig)  # Remove it properly.
        else:
            self._add_callback_signalsafe(handle)

    def remove_signal_handler(self, sig):
        """Remove a handler for a signal.  UNIX only.

        Return True if a signal handler was removed, False if not.
        """
        self._check_signal(sig)
        try:
            del self._signal_handlers[sig]
        except KeyError:
            return False

        if sig == signal.SIGINT:
            handler = signal.default_int_handler
        else:
            handler = signal.SIG_DFL

        try:
            signal.signal(sig, handler)
        except OSError as exc:
            if exc.errno == errno.EINVAL:
                raise RuntimeError('sig {} cannot be caught'.format(sig))
            else:
                raise

        if not self._signal_handlers:
            try:
                signal.set_wakeup_fd(-1)
            except (ValueError, OSError) as exc:
                logger.info('set_wakeup_fd(-1) failed: %s', exc)

        return True

    def _check_signal(self, sig):
        """Internal helper to validate a signal.

        Raise ValueError if the signal number is invalid or uncatchable.
        Raise RuntimeError if there is a problem setting up the handler.
        """
        if not isinstance(sig, int):
            raise TypeError('sig must be an int, not {!r}'.format(sig))

        if not (1 <= sig < signal.NSIG):
            raise ValueError(
                'sig {} out of range(1, {})'.format(sig, signal.NSIG))

    def _make_read_pipe_transport(self, pipe, protocol, waiter=None,
                                  extra=None):
        return _UnixReadPipeTransport(self, pipe, protocol, waiter, extra)

    def _make_write_pipe_transport(self, pipe, protocol, waiter=None,
                                   extra=None):
        return _UnixWritePipeTransport(self, pipe, protocol, waiter, extra)

    @coroutine
    def _make_subprocess_transport(self, protocol, args, shell,
                                   stdin, stdout, stderr, bufsize,
                                   extra=None, **kwargs):
        with events.get_child_watcher() as watcher:
            waiter = futures.Future(loop=self)
            transp = _UnixSubprocessTransport(self, protocol, args, shell,
                                              stdin, stdout, stderr, bufsize,
                                              waiter=waiter, extra=extra,
                                              **kwargs)

            watcher.add_child_handler(transp.get_pid(),
                                      self._child_watcher_callback, transp)
            try:
                yield from waiter
            except Exception as exc:
                # Workaround CPython bug #23353: using yield/yield-from in an
                # except block of a generator doesn't clear properly
                # sys.exc_info()
                err = exc
            else:
                err = None

            if err is not None:
                transp.close()
                yield from transp._wait()
                raise err

        return transp

    def _child_watcher_callback(self, pid, returncode, transp):
        self.call_soon_threadsafe(transp._process_exited, returncode)

    @coroutine
    def create_unix_connection(self, protocol_factory, path, *,
                               ssl=None, sock=None,
                               server_hostname=None):
        assert server_hostname is None or isinstance(server_hostname, str)
        if ssl:
            if server_hostname is None:
                raise ValueError(
                    'you have to pass server_hostname when using ssl')
        else:
            if server_hostname is not None:
                raise ValueError('server_hostname is only meaningful with ssl')

        if path is not None:
            if sock is not None:
                raise ValueError(
                    'path and sock can not be specified at the same time')

            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
            try:
                sock.setblocking(False)
                yield from self.sock_connect(sock, path)
            except:
                sock.close()
                raise

        else:
            if sock is None:
                raise ValueError('no path and sock were specified')
            sock.setblocking(False)

        transport, protocol = yield from self._create_connection_transport(
            sock, protocol_factory, ssl, server_hostname)
        return transport, protocol

    @coroutine
    def create_unix_server(self, protocol_factory, path=None, *,
                           sock=None, backlog=100, ssl=None):
        if isinstance(ssl, bool):
            raise TypeError('ssl argument must be an SSLContext or None')

        if path is not None:
            if sock is not None:
                raise ValueError(
                    'path and sock can not be specified at the same time')

            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

            try:
                sock.bind(path)
            except OSError as exc:
                sock.close()
                if exc.errno == errno.EADDRINUSE:
                    # Let's improve the error message by adding
                    # with what exact address it occurs.
                    msg = 'Address {!r} is already in use'.format(path)
                    raise OSError(errno.EADDRINUSE, msg) from None
                else:
                    raise
            except:
                sock.close()
                raise
        else:
            if sock is None:
                raise ValueError(
                    'path was not specified, and no sock specified')

            if sock.family != socket.AF_UNIX:
                raise ValueError(
                    'A UNIX Domain Socket was expected, got {!r}'.format(sock))

        server = base_events.Server(self, [sock])
        sock.listen(backlog)
        sock.setblocking(False)
        self._start_serving(protocol_factory, sock, ssl, server)
        return server

Ancestors (in MRO)

  • loop_cls
  • asyncio.selector_events.BaseSelectorEventLoop
  • asyncio.base_events.BaseEventLoop
  • asyncio.events.AbstractEventLoop
  • builtins.object

Static methods

def __init__(

self, selector=None)

def __init__(self, selector=None):
    super().__init__(selector)
    self._signal_handlers = {}

def add_reader(

self, fd, callback, *args)

Add a reader callback.

def add_reader(self, fd, callback, *args):
    """Add a reader callback."""
    self._check_closed()
    handle = events.Handle(callback, args, self)
    try:
        key = self._selector.get_key(fd)
    except KeyError:
        self._selector.register(fd, selectors.EVENT_READ,
                                (handle, None))
    else:
        mask, (reader, writer) = key.events, key.data
        self._selector.modify(fd, mask | selectors.EVENT_READ,
                              (handle, writer))
        if reader is not None:
            reader.cancel()

def add_signal_handler(

self, sig, callback, *args)

Add a handler for a signal. UNIX only.

Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler.

def add_signal_handler(self, sig, callback, *args):
    """Add a handler for a signal.  UNIX only.
    Raise ValueError if the signal number is invalid or uncatchable.
    Raise RuntimeError if there is a problem setting up the handler.
    """
    if (coroutines.iscoroutine(callback)
    or coroutines.iscoroutinefunction(callback)):
        raise TypeError("coroutines cannot be used "
                        "with add_signal_handler()")
    self._check_signal(sig)
    self._check_closed()
    try:
        # set_wakeup_fd() raises ValueError if this is not the
        # main thread.  By calling it early we ensure that an
        # event loop running in another thread cannot add a signal
        # handler.
        signal.set_wakeup_fd(self._csock.fileno())
    except (ValueError, OSError) as exc:
        raise RuntimeError(str(exc))
    handle = events.Handle(callback, args, self)
    self._signal_handlers[sig] = handle
    try:
        # Register a dummy signal handler to ask Python to write the signal
        # number in the wakup file descriptor. _process_self_data() will
        # read signal numbers from this file descriptor to handle signals.
        signal.signal(sig, _sighandler_noop)
        # Set SA_RESTART to limit EINTR occurrences.
        signal.siginterrupt(sig, False)
    except OSError as exc:
        del self._signal_handlers[sig]
        if not self._signal_handlers:
            try:
                signal.set_wakeup_fd(-1)
            except (ValueError, OSError) as nexc:
                logger.info('set_wakeup_fd(-1) failed: %s', nexc)
        if exc.errno == errno.EINVAL:
            raise RuntimeError('sig {} cannot be caught'.format(sig))
        else:
            raise

def add_writer(

self, fd, callback, *args)

Add a writer callback..

def add_writer(self, fd, callback, *args):
    """Add a writer callback.."""
    self._check_closed()
    handle = events.Handle(callback, args, self)
    try:
        key = self._selector.get_key(fd)
    except KeyError:
        self._selector.register(fd, selectors.EVENT_WRITE,
                                (None, handle))
    else:
        mask, (reader, writer) = key.events, key.data
        self._selector.modify(fd, mask | selectors.EVENT_WRITE,
                              (reader, handle))
        if writer is not None:
            writer.cancel()

def call_at(

self, when, callback, *args)

Like call_later(), but uses an absolute time.

Absolute time corresponds to the event loop's time() method.

def call_at(self, when, callback, *args):
    """Like call_later(), but uses an absolute time.
    Absolute time corresponds to the event loop's time() method.
    """
    if (coroutines.iscoroutine(callback)
    or coroutines.iscoroutinefunction(callback)):
        raise TypeError("coroutines cannot be used with call_at()")
    self._check_closed()
    if self._debug:
        self._check_thread()
    timer = events.TimerHandle(when, callback, args, self)
    if timer._source_traceback:
        del timer._source_traceback[-1]
    heapq.heappush(self._scheduled, timer)
    timer._scheduled = True
    return timer

def call_exception_handler(

self, context)

Call the current event loop's exception handler.

The context argument is a dict containing the following keys:

  • 'message': Error message;
  • 'exception' (optional): Exception object;
  • 'future' (optional): Future instance;
  • 'handle' (optional): Handle instance;
  • 'protocol' (optional): Protocol instance;
  • 'transport' (optional): Transport instance;
  • 'socket' (optional): Socket instance.

New keys maybe introduced in the future.

Note: do not overload this method in an event loop subclass. For custom exception handling, use the set_exception_handler() method.

def call_exception_handler(self, context):
    """Call the current event loop's exception handler.
    The context argument is a dict containing the following keys:
    - 'message': Error message;
    - 'exception' (optional): Exception object;
    - 'future' (optional): Future instance;
    - 'handle' (optional): Handle instance;
    - 'protocol' (optional): Protocol instance;
    - 'transport' (optional): Transport instance;
    - 'socket' (optional): Socket instance.
    New keys maybe introduced in the future.
    Note: do not overload this method in an event loop subclass.
    For custom exception handling, use the
    `set_exception_handler()` method.
    """
    if self._exception_handler is None:
        try:
            self.default_exception_handler(context)
        except Exception:
            # Second protection layer for unexpected errors
            # in the default implementation, as well as for subclassed
            # event loops with overloaded "default_exception_handler".
            logger.error('Exception in default exception handler',
                         exc_info=True)
    else:
        try:
            self._exception_handler(self, context)
        except Exception as exc:
            # Exception in the user set custom exception handler.
            try:
                # Let's try default handler.
                self.default_exception_handler({
                    'message': 'Unhandled error in exception handler',
                    'exception': exc,
                    'context': context,
                })
            except Exception:
                # Guard 'default_exception_handler' in case it is
                # overloaded.
                logger.error('Exception in default exception handler '
                             'while handling an unexpected error '
                             'in custom exception handler',
                             exc_info=True)

def call_later(

self, delay, callback, *args)

Arrange for a callback to be called at a given time.

Return a Handle: an opaque object with a cancel() method that can be used to cancel the call.

The delay can be an int or float, expressed in seconds. It is always relative to the current time.

Each callback will be called exactly once. If two callbacks are scheduled for exactly the same time, it undefined which will be called first.

Any positional arguments after the callback will be passed to the callback when it is called.

def call_later(self, delay, callback, *args):
    """Arrange for a callback to be called at a given time.
    Return a Handle: an opaque object with a cancel() method that
    can be used to cancel the call.
    The delay can be an int or float, expressed in seconds.  It is
    always relative to the current time.
    Each callback will be called exactly once.  If two callbacks
    are scheduled for exactly the same time, it undefined which
    will be called first.
    Any positional arguments after the callback will be passed to
    the callback when it is called.
    """
    timer = self.call_at(self.time() + delay, callback, *args)
    if timer._source_traceback:
        del timer._source_traceback[-1]
    return timer

def call_soon(

self, callback, *args)

Arrange for a callback to be called as soon as possible.

This operates as a FIFO queue: callbacks are called in the order in which they are registered. Each callback will be called exactly once.

Any positional arguments after the callback will be passed to the callback when it is called.

def call_soon(self, callback, *args):
    """Arrange for a callback to be called as soon as possible.
    This operates as a FIFO queue: callbacks are called in the
    order in which they are registered.  Each callback will be
    called exactly once.
    Any positional arguments after the callback will be passed to
    the callback when it is called.
    """
    if self._debug:
        self._check_thread()
    handle = self._call_soon(callback, args)
    if handle._source_traceback:
        del handle._source_traceback[-1]
    return handle

def call_soon_threadsafe(

self, callback, *args)

Like call_soon(), but thread-safe.

def call_soon_threadsafe(self, callback, *args):
    """Like call_soon(), but thread-safe."""
    handle = self._call_soon(callback, args)
    if handle._source_traceback:
        del handle._source_traceback[-1]
    self._write_to_self()
    return handle

def close(

self)

def close(self):
    super().close()
    for sig in list(self._signal_handlers):
        self.remove_signal_handler(sig)

def connect_read_pipe(

self, protocol_factory, pipe)

@coroutine
def connect_read_pipe(self, protocol_factory, pipe):
    protocol = protocol_factory()
    waiter = futures.Future(loop=self)
    transport = self._make_read_pipe_transport(pipe, protocol, waiter)
    try:
        yield from waiter
    except:
        transport.close()
        raise
    if self._debug:
        logger.debug('Read pipe %r connected: (%r, %r)',
                     pipe.fileno(), transport, protocol)
    return transport, protocol

def connect_write_pipe(

self, protocol_factory, pipe)

@coroutine
def connect_write_pipe(self, protocol_factory, pipe):
    protocol = protocol_factory()
    waiter = futures.Future(loop=self)
    transport = self._make_write_pipe_transport(pipe, protocol, waiter)
    try:
        yield from waiter
    except:
        transport.close()
        raise
    if self._debug:
        logger.debug('Write pipe %r connected: (%r, %r)',
                     pipe.fileno(), transport, protocol)
    return transport, protocol

def create_connection(

self, protocol_factory, host=None, port=None)

Connect to a TCP server.

Create a streaming transport connection to a given Internet host and port: socket family AF_INET or socket.AF_INET6 depending on host (or family if specified), socket type SOCK_STREAM. protocol_factory must be a callable returning a protocol instance.

This method is a coroutine which will try to establish the connection in the background. When successful, the coroutine returns a (transport, protocol) pair.

@coroutine
def create_connection(self, protocol_factory, host=None, port=None, *,
                      ssl=None, family=0, proto=0, flags=0, sock=None,
                      local_addr=None, server_hostname=None):
    """Connect to a TCP server.
    Create a streaming transport connection to a given Internet host and
    port: socket family AF_INET or socket.AF_INET6 depending on host (or
    family if specified), socket type SOCK_STREAM. protocol_factory must be
    a callable returning a protocol instance.
    This method is a coroutine which will try to establish the connection
    in the background.  When successful, the coroutine returns a
    (transport, protocol) pair.
    """
    if server_hostname is not None and not ssl:
        raise ValueError('server_hostname is only meaningful with ssl')
    if server_hostname is None and ssl:
        # Use host as default for server_hostname.  It is an error
        # if host is empty or not set, e.g. when an
        # already-connected socket was passed or when only a port
        # is given.  To avoid this error, you can pass
        # server_hostname='' -- this will bypass the hostname
        # check.  (This also means that if host is a numeric
        # IP/IPv6 address, we will attempt to verify that exact
        # address; this will probably fail, but it is possible to
        # create a certificate for a specific IP address, so we
        # don't judge it here.)
        if not host:
            raise ValueError('You must set server_hostname '
                             'when using ssl without a host')
        server_hostname = host
    if host is not None or port is not None:
        if sock is not None:
            raise ValueError(
                'host/port and sock can not be specified at the same time')
        f1 = self.getaddrinfo(
            host, port, family=family,
            type=socket.SOCK_STREAM, proto=proto, flags=flags)
        fs = [f1]
        if local_addr is not None:
            f2 = self.getaddrinfo(
                *local_addr, family=family,
                type=socket.SOCK_STREAM, proto=proto, flags=flags)
            fs.append(f2)
        else:
            f2 = None
        yield from tasks.wait(fs, loop=self)
        infos = f1.result()
        if not infos:
            raise OSError('getaddrinfo() returned empty list')
        if f2 is not None:
            laddr_infos = f2.result()
            if not laddr_infos:
                raise OSError('getaddrinfo() returned empty list')
        exceptions = []
        for family, type, proto, cname, address in infos:
            try:
                sock = socket.socket(family=family, type=type, proto=proto)
                sock.setblocking(False)
                if f2 is not None:
                    for _, _, _, _, laddr in laddr_infos:
                        try:
                            sock.bind(laddr)
                            break
                        except OSError as exc:
                            exc = OSError(
                                exc.errno, 'error while '
                                'attempting to bind on address '
                                '{!r}: {}'.format(
                                    laddr, exc.strerror.lower()))
                            exceptions.append(exc)
                    else:
                        sock.close()
                        sock = None
                        continue
                if self._debug:
                    logger.debug("connect %r to %r", sock, address)
                yield from self.sock_connect(sock, address)
            except OSError as exc:
                if sock is not None:
                    sock.close()
                exceptions.append(exc)
            except:
                if sock is not None:
                    sock.close()
                raise
            else:
                break
        else:
            if len(exceptions) == 1:
                raise exceptions[0]
            else:
                # If they all have the same str(), raise one.
                model = str(exceptions[0])
                if all(str(exc) == model for exc in exceptions):
                    raise exceptions[0]
                # Raise a combined exception so the user can see all
                # the various error messages.
                raise OSError('Multiple exceptions: {}'.format(
                    ', '.join(str(exc) for exc in exceptions)))
    elif sock is None:
        raise ValueError(
            'host and port was not specified and no sock specified')
    sock.setblocking(False)
    transport, protocol = yield from self._create_connection_transport(
        sock, protocol_factory, ssl, server_hostname)
    if self._debug:
        # Get the socket from the transport because SSL transport closes
        # the old socket and creates a new SSL socket
        sock = transport.get_extra_info('socket')
        logger.debug("%r connected to %s:%r: (%r, %r)",
                     sock, host, port, transport, protocol)
    return transport, protocol

def create_datagram_endpoint(

self, protocol_factory, local_addr=None, remote_addr=None)

Create datagram connection.

@coroutine
def create_datagram_endpoint(self, protocol_factory,
                             local_addr=None, remote_addr=None, *,
                             family=0, proto=0, flags=0,
                             reuse_address=None, reuse_port=None,
                             allow_broadcast=None, sock=None):
    """Create datagram connection."""
    if sock is not None:
        if (local_addr or remote_addr or
                family or proto or flags or
                reuse_address or reuse_port or allow_broadcast):
            # show the problematic kwargs in exception msg
            opts = dict(local_addr=local_addr, remote_addr=remote_addr,
                        family=family, proto=proto, flags=flags,
                        reuse_address=reuse_address, reuse_port=reuse_port,
                        allow_broadcast=allow_broadcast)
            problems = ', '.join(
                '{}={}'.format(k, v) for k, v in opts.items() if v)
            raise ValueError(
                'socket modifier keyword arguments can not be used '
                'when sock is specified. ({})'.format(problems))
        sock.setblocking(False)
        r_addr = None
    else:
        if not (local_addr or remote_addr):
            if family == 0:
                raise ValueError('unexpected address family')
            addr_pairs_info = (((family, proto), (None, None)),)
        else:
            # join address by (family, protocol)
            addr_infos = collections.OrderedDict()
            for idx, addr in ((0, local_addr), (1, remote_addr)):
                if addr is not None:
                    assert isinstance(addr, tuple) and len(addr) == 2, (
                        '2-tuple is expected')
                    infos = yield from self.getaddrinfo(
                        *addr, family=family, type=socket.SOCK_DGRAM,
                        proto=proto, flags=flags)
                    if not infos:
                        raise OSError('getaddrinfo() returned empty list')
                    for fam, _, pro, _, address in infos:
                        key = (fam, pro)
                        if key not in addr_infos:
                            addr_infos[key] = [None, None]
                        addr_infos[key][idx] = address
            # each addr has to have info for each (family, proto) pair
            addr_pairs_info = [
                (key, addr_pair) for key, addr_pair in addr_infos.items()
                if not ((local_addr and addr_pair[0] is None) or
                        (remote_addr and addr_pair[1] is None))]
            if not addr_pairs_info:
                raise ValueError('can not get address information')
        exceptions = []
        if reuse_address is None:
            reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
        for ((family, proto),
             (local_address, remote_address)) in addr_pairs_info:
            sock = None
            r_addr = None
            try:
                sock = socket.socket(
                    family=family, type=socket.SOCK_DGRAM, proto=proto)
                if reuse_address:
                    sock.setsockopt(
                        socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                if reuse_port:
                    if not hasattr(socket, 'SO_REUSEPORT'):
                        raise ValueError(
                            'reuse_port not supported by socket module')
                    else:
                        sock.setsockopt(
                            socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
                if allow_broadcast:
                    sock.setsockopt(
                        socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
                sock.setblocking(False)
                if local_addr:
                    sock.bind(local_address)
                if remote_addr:
                    yield from self.sock_connect(sock, remote_address)
                    r_addr = remote_address
            except OSError as exc:
                if sock is not None:
                    sock.close()
                exceptions.append(exc)
            except:
                if sock is not None:
                    sock.close()
                raise
            else:
                break
        else:
            raise exceptions[0]
    protocol = protocol_factory()
    waiter = futures.Future(loop=self)
    transport = self._make_datagram_transport(
        sock, protocol, r_addr, waiter)
    if self._debug:
        if local_addr:
            logger.info("Datagram endpoint local_addr=%r remote_addr=%r "
                        "created: (%r, %r)",
                        local_addr, remote_addr, transport, protocol)
        else:
            logger.debug("Datagram endpoint remote_addr=%r created: "
                         "(%r, %r)",
                         remote_addr, transport, protocol)
    try:
        yield from waiter
    except:
        transport.close()
        raise
    return transport, protocol

def create_server(

self, protocol_factory, host=None, port=None)

Create a TCP server.

The host parameter can be a string, in that case the TCP server is bound to host and port.

The host parameter can also be a sequence of strings and in that case the TCP server is bound to all hosts of the sequence.

Return a Server object which can be used to stop the service.

This method is a coroutine.

@coroutine
def create_server(self, 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):
    """Create a TCP server.
    The host parameter can be a string, in that case the TCP server is bound
    to host and port.
    The host parameter can also be a sequence of strings and in that case
    the TCP server is bound to all hosts of the sequence.
    Return a Server object which can be used to stop the service.
    This method is a coroutine.
    """
    if isinstance(ssl, bool):
        raise TypeError('ssl argument must be an SSLContext or None')
    if host is not None or port is not None:
        if sock is not None:
            raise ValueError(
                'host/port and sock can not be specified at the same time')
        AF_INET6 = getattr(socket, 'AF_INET6', 0)
        if reuse_address is None:
            reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
        sockets = []
        if host == '':
            hosts = [None]
        elif (isinstance(host, str) or
              not isinstance(host, collections.Iterable)):
            hosts = [host]
        else:
            hosts = host
        fs = [self._create_server_getaddrinfo(host, port, family=family,
                                              flags=flags)
              for host in hosts]
        infos = yield from tasks.gather(*fs, loop=self)
        infos = itertools.chain.from_iterable(infos)
        completed = False
        try:
            for res in infos:
                af, socktype, proto, canonname, sa = res
                try:
                    sock = socket.socket(af, socktype, proto)
                except socket.error:
                    # Assume it's a bad family/type/protocol combination.
                    if self._debug:
                        logger.warning('create_server() failed to create '
                                       'socket.socket(%r, %r, %r)',
                                       af, socktype, proto, exc_info=True)
                    continue
                sockets.append(sock)
                if reuse_address:
                    sock.setsockopt(
                        socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
                if reuse_port:
                    if not hasattr(socket, 'SO_REUSEPORT'):
                        raise ValueError(
                            'reuse_port not supported by socket module')
                    else:
                        sock.setsockopt(
                            socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
                # Disable IPv4/IPv6 dual stack support (enabled by
                # default on Linux) which makes a single socket
                # listen on both address families.
                if af == AF_INET6 and hasattr(socket, 'IPPROTO_IPV6'):
                    sock.setsockopt(socket.IPPROTO_IPV6,
                                    socket.IPV6_V6ONLY,
                                    True)
                try:
                    sock.bind(sa)
                except OSError as err:
                    raise OSError(err.errno, 'error while attempting '
                                  'to bind on address %r: %s'
                                  % (sa, err.strerror.lower()))
            completed = True
        finally:
            if not completed:
                for sock in sockets:
                    sock.close()
    else:
        if sock is None:
            raise ValueError('Neither host/port nor sock were specified')
        sockets = [sock]
    server = Server(self, sockets)
    for sock in sockets:
        sock.listen(backlog)
        sock.setblocking(False)
        self._start_serving(protocol_factory, sock, ssl, server)
    if self._debug:
        logger.info("%r is serving", server)
    return server

def create_task(

self, coro)

Schedule a coroutine object.

Return a task object.

def create_task(self, coro):
    """Schedule a coroutine object.
    Return a task object.
    """
    self._check_closed()
    if self._task_factory is None:
        task = tasks.Task(coro, loop=self)
        if task._source_traceback:
            del task._source_traceback[-1]
    else:
        task = self._task_factory(self, coro)
    return task

def create_unix_connection(

self, protocol_factory, path)

@coroutine
def create_unix_connection(self, protocol_factory, path, *,
                           ssl=None, sock=None,
                           server_hostname=None):
    assert server_hostname is None or isinstance(server_hostname, str)
    if ssl:
        if server_hostname is None:
            raise ValueError(
                'you have to pass server_hostname when using ssl')
    else:
        if server_hostname is not None:
            raise ValueError('server_hostname is only meaningful with ssl')
    if path is not None:
        if sock is not None:
            raise ValueError(
                'path and sock can not be specified at the same time')
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
        try:
            sock.setblocking(False)
            yield from self.sock_connect(sock, path)
        except:
            sock.close()
            raise
    else:
        if sock is None:
            raise ValueError('no path and sock were specified')
        sock.setblocking(False)
    transport, protocol = yield from self._create_connection_transport(
        sock, protocol_factory, ssl, server_hostname)
    return transport, protocol

def create_unix_server(

*args, **kw)

@coroutine
def create_unix_server(self, protocol_factory, path=None, *,
                       sock=None, backlog=100, ssl=None):
    if isinstance(ssl, bool):
        raise TypeError('ssl argument must be an SSLContext or None')
    if path is not None:
        if sock is not None:
            raise ValueError(
                'path and sock can not be specified at the same time')
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        try:
            sock.bind(path)
        except OSError as exc:
            sock.close()
            if exc.errno == errno.EADDRINUSE:
                # Let's improve the error message by adding
                # with what exact address it occurs.
                msg = 'Address {!r} is already in use'.format(path)
                raise OSError(errno.EADDRINUSE, msg) from None
            else:
                raise
        except:
            sock.close()
            raise
    else:
        if sock is None:
            raise ValueError(
                'path was not specified, and no sock specified')
        if sock.family != socket.AF_UNIX:
            raise ValueError(
                'A UNIX Domain Socket was expected, got {!r}'.format(sock))
    server = base_events.Server(self, [sock])
    sock.listen(backlog)
    sock.setblocking(False)
    self._start_serving(protocol_factory, sock, ssl, server)
    return server

def default_exception_handler(

self, context)

Default exception handler.

This is called when an exception occurs and no exception handler is set, and can be called by a custom exception handler that wants to defer to the default behavior.

The context parameter has the same meaning as in call_exception_handler().

def default_exception_handler(self, context):
    """Default exception handler.
    This is called when an exception occurs and no exception
    handler is set, and can be called by a custom exception
    handler that wants to defer to the default behavior.
    The context parameter has the same meaning as in
    `call_exception_handler()`.
    """
    message = context.get('message')
    if not message:
        message = 'Unhandled exception in event loop'
    exception = context.get('exception')
    if exception is not None:
        exc_info = (type(exception), exception, exception.__traceback__)
    else:
        exc_info = False
    if ('source_traceback' not in context
    and self._current_handle is not None
    and self._current_handle._source_traceback):
        context['handle_traceback'] = self._current_handle._source_traceback
    log_lines = [message]
    for key in sorted(context):
        if key in {'message', 'exception'}:
            continue
        value = context[key]
        if key == 'source_traceback':
            tb = ''.join(traceback.format_list(value))
            value = 'Object created at (most recent call last):\n'
            value += tb.rstrip()
        elif key == 'handle_traceback':
            tb = ''.join(traceback.format_list(value))
            value = 'Handle created at (most recent call last):\n'
            value += tb.rstrip()
        else:
            value = repr(value)
        log_lines.append('{}: {}'.format(key, value))
    logger.error('\n'.join(log_lines), exc_info=exc_info)

def get_debug(

self)

def get_debug(self):
    return self._debug

def get_task_factory(

self)

Return a task factory, or None if the default one is in use.

def get_task_factory(self):
    """Return a task factory, or None if the default one is in use."""
    return self._task_factory

def getaddrinfo(

self, host, port)

def getaddrinfo(self, host, port, *,
                family=0, type=0, proto=0, flags=0):
    if self._debug:
        return self.run_in_executor(None, self._getaddrinfo_debug,
                                    host, port, family, type, proto, flags)
    else:
        return self.run_in_executor(None, socket.getaddrinfo,
                                    host, port, family, type, proto, flags)

def getnameinfo(

self, sockaddr, flags=0)

def getnameinfo(self, sockaddr, flags=0):
    return self.run_in_executor(None, socket.getnameinfo, sockaddr, flags)

def is_closed(

self)

Returns True if the event loop was closed.

def is_closed(self):
    """Returns True if the event loop was closed."""
    return self._closed

def is_running(

self)

Returns True if the event loop is running.

def is_running(self):
    """Returns True if the event loop is running."""
    return (self._thread_id is not None)

def remove_reader(

self, fd)

Remove a reader callback.

def remove_reader(self, fd):
    """Remove a reader callback."""
    if self.is_closed():
        return False
    try:
        key = self._selector.get_key(fd)
    except KeyError:
        return False
    else:
        mask, (reader, writer) = key.events, key.data
        mask &= ~selectors.EVENT_READ
        if not mask:
            self._selector.unregister(fd)
        else:
            self._selector.modify(fd, mask, (None, writer))
        if reader is not None:
            reader.cancel()
            return True
        else:
            return False

def remove_signal_handler(

self, sig)

Remove a handler for a signal. UNIX only.

Return True if a signal handler was removed, False if not.

def remove_signal_handler(self, sig):
    """Remove a handler for a signal.  UNIX only.
    Return True if a signal handler was removed, False if not.
    """
    self._check_signal(sig)
    try:
        del self._signal_handlers[sig]
    except KeyError:
        return False
    if sig == signal.SIGINT:
        handler = signal.default_int_handler
    else:
        handler = signal.SIG_DFL
    try:
        signal.signal(sig, handler)
    except OSError as exc:
        if exc.errno == errno.EINVAL:
            raise RuntimeError('sig {} cannot be caught'.format(sig))
        else:
            raise
    if not self._signal_handlers:
        try:
            signal.set_wakeup_fd(-1)
        except (ValueError, OSError) as exc:
            logger.info('set_wakeup_fd(-1) failed: %s', exc)
    return True

def remove_writer(

self, fd)

Remove a writer callback.

def remove_writer(self, fd):
    """Remove a writer callback."""
    if self.is_closed():
        return False
    try:
        key = self._selector.get_key(fd)
    except KeyError:
        return False
    else:
        mask, (reader, writer) = key.events, key.data
        # Remove both writer and connector.
        mask &= ~selectors.EVENT_WRITE
        if not mask:
            self._selector.unregister(fd)
        else:
            self._selector.modify(fd, mask, (reader, None))
        if writer is not None:
            writer.cancel()
            return True
        else:
            return False

def run_forever(

self)

Run until stop() is called.

def run_forever(self):
    """Run until stop() is called."""
    self._check_closed()
    if self.is_running():
        raise RuntimeError('Event loop is running.')
    self._set_coroutine_wrapper(self._debug)
    self._thread_id = threading.get_ident()
    try:
        while True:
            self._run_once()
            if self._stopping:
                break
    finally:
        self._stopping = False
        self._thread_id = None
        self._set_coroutine_wrapper(False)

def run_in_executor(

self, executor, func, *args)

def run_in_executor(self, executor, func, *args):
    if (coroutines.iscoroutine(func)
    or coroutines.iscoroutinefunction(func)):
        raise TypeError("coroutines cannot be used with run_in_executor()")
    self._check_closed()
    if isinstance(func, events.Handle):
        assert not args
        assert not isinstance(func, events.TimerHandle)
        if func._cancelled:
            f = futures.Future(loop=self)
            f.set_result(None)
            return f
        func, args = func._callback, func._args
    if executor is None:
        executor = self._default_executor
        if executor is None:
            executor = concurrent.futures.ThreadPoolExecutor(_MAX_WORKERS)
            self._default_executor = executor
    return futures.wrap_future(executor.submit(func, *args), loop=self)

def run_until_complete(

self, future)

Run until the Future is done.

If the argument is a coroutine, it is wrapped in a Task.

WARNING: It would be disastrous to call run_until_complete() with the same coroutine twice -- it would wrap it in two different Tasks and that can't be good.

Return the Future's result, or raise its exception.

def run_until_complete(self, future):
    """Run until the Future is done.
    If the argument is a coroutine, it is wrapped in a Task.
    WARNING: It would be disastrous to call run_until_complete()
    with the same coroutine twice -- it would wrap it in two
    different Tasks and that can't be good.
    Return the Future's result, or raise its exception.
    """
    self._check_closed()
    new_task = not isinstance(future, futures.Future)
    future = tasks.ensure_future(future, loop=self)
    if new_task:
        # An exception is raised if the future didn't complete, so there
        # is no need to log the "destroy pending task" message
        future._log_destroy_pending = False
    future.add_done_callback(_run_until_complete_cb)
    try:
        self.run_forever()
    except:
        if new_task and future.done() and not future.cancelled():
            # The coroutine raised a BaseException. Consume the exception
            # to not log a warning, the caller doesn't have access to the
            # local task.
            future.exception()
        raise
    future.remove_done_callback(_run_until_complete_cb)
    if not future.done():
        raise RuntimeError('Event loop stopped before Future completed.')
    return future.result()

def set_debug(

self, enabled)

def set_debug(self, enabled):
    self._debug = enabled
    if self.is_running():
        self._set_coroutine_wrapper(enabled)

def set_default_executor(

self, executor)

def set_default_executor(self, executor):
    self._default_executor = executor

def set_exception_handler(

self, handler)

Set handler as the new event loop exception handler.

If handler is None, the default exception handler will be set.

If handler is a callable object, it should have a signature matching '(loop, context)', where 'loop' will be a reference to the active event loop, 'context' will be a dict object (see call_exception_handler() documentation for details about context).

def set_exception_handler(self, handler):
    """Set handler as the new event loop exception handler.
    If handler is None, the default exception handler will
    be set.
    If handler is a callable object, it should have a
    signature matching '(loop, context)', where 'loop'
    will be a reference to the active event loop, 'context'
    will be a dict object (see `call_exception_handler()`
    documentation for details about context).
    """
    if handler is not None and not callable(handler):
        raise TypeError('A callable object or None is expected, '
                        'got {!r}'.format(handler))
    self._exception_handler = handler

def set_task_factory(

self, factory)

Set a task factory that will be used by loop.create_task().

If factory is None the default task factory will be set.

If factory is a callable, it should have a signature matching '(loop, coro)', where 'loop' will be a reference to the active event loop, 'coro' will be a coroutine object. The callable must return a Future.

def set_task_factory(self, factory):
    """Set a task factory that will be used by loop.create_task().
    If factory is None the default task factory will be set.
    If factory is a callable, it should have a signature matching
    '(loop, coro)', where 'loop' will be a reference to the active
    event loop, 'coro' will be a coroutine object.  The callable
    must return a Future.
    """
    if factory is not None and not callable(factory):
        raise TypeError('task factory must be a callable or None')
    self._task_factory = factory

def sock_accept(

self, sock)

Accept a connection.

The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

This method is a coroutine.

def sock_accept(self, sock):
    """Accept a connection.
    The socket must be bound to an address and listening for connections.
    The return value is a pair (conn, address) where conn is a new socket
    object usable to send and receive data on the connection, and address
    is the address bound to the socket on the other end of the connection.
    This method is a coroutine.
    """
    if self._debug and sock.gettimeout() != 0:
        raise ValueError("the socket must be non-blocking")
    fut = futures.Future(loop=self)
    self._sock_accept(fut, False, sock)
    return fut

def sock_connect(

self, sock, address)

Connect to a remote socket at address.

The address must be already resolved to avoid the trap of hanging the entire event loop when the address requires doing a DNS lookup. For example, it must be an IP address, not an hostname, for AF_INET and AF_INET6 address families. Use getaddrinfo() to resolve the hostname asynchronously.

This method is a coroutine.

def sock_connect(self, sock, address):
    """Connect to a remote socket at address.
    The address must be already resolved to avoid the trap of hanging the
    entire event loop when the address requires doing a DNS lookup. For
    example, it must be an IP address, not an hostname, for AF_INET and
    AF_INET6 address families. Use getaddrinfo() to resolve the hostname
    asynchronously.
    This method is a coroutine.
    """
    if self._debug and sock.gettimeout() != 0:
        raise ValueError("the socket must be non-blocking")
    fut = futures.Future(loop=self)
    try:
        if self._debug:
            base_events._check_resolved_address(sock, address)
    except ValueError as err:
        fut.set_exception(err)
    else:
        self._sock_connect(fut, sock, address)
    return fut

def sock_recv(

self, sock, n)

Receive data from the socket.

The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by nbytes.

This method is a coroutine.

def sock_recv(self, sock, n):
    """Receive data from the socket.
    The return value is a bytes object representing the data received.
    The maximum amount of data to be received at once is specified by
    nbytes.
    This method is a coroutine.
    """
    if self._debug and sock.gettimeout() != 0:
        raise ValueError("the socket must be non-blocking")
    fut = futures.Future(loop=self)
    self._sock_recv(fut, False, sock, n)
    return fut

def sock_sendall(

self, sock, data)

Send data to the socket.

The socket must be connected to a remote socket. This method continues to send data from data until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully processed by the receiving end of the connection.

This method is a coroutine.

def sock_sendall(self, sock, data):
    """Send data to the socket.
    The socket must be connected to a remote socket. This method continues
    to send data from data until either all data has been sent or an
    error occurs. None is returned on success. On error, an exception is
    raised, and there is no way to determine how much data, if any, was
    successfully processed by the receiving end of the connection.
    This method is a coroutine.
    """
    if self._debug and sock.gettimeout() != 0:
        raise ValueError("the socket must be non-blocking")
    fut = futures.Future(loop=self)
    if data:
        self._sock_sendall(fut, False, sock, data)
    else:
        fut.set_result(None)
    return fut

def stop(

self)

Stop running the event loop.

Every callback already scheduled will still run. This simply informs run_forever to stop looping after a complete iteration.

def stop(self):
    """Stop running the event loop.
    Every callback already scheduled will still run.  This simply informs
    run_forever to stop looping after a complete iteration.
    """
    self._stopping = True

def subprocess_exec(

self, protocol_factory, program, *args, **kwargs)

@coroutine
def subprocess_exec(self, protocol_factory, program, *args,
                    stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE, universal_newlines=False,
                    shell=False, bufsize=0, **kwargs):
    if universal_newlines:
        raise ValueError("universal_newlines must be False")
    if shell:
        raise ValueError("shell must be False")
    if bufsize != 0:
        raise ValueError("bufsize must be 0")
    popen_args = (program,) + args
    for arg in popen_args:
        if not isinstance(arg, (str, bytes)):
            raise TypeError("program arguments must be "
                            "a bytes or text string, not %s"
                            % type(arg).__name__)
    protocol = protocol_factory()
    if self._debug:
        # don't log parameters: they may contain sensitive information
        # (password) and may be too long
        debug_log = 'execute program %r' % program
        self._log_subprocess(debug_log, stdin, stdout, stderr)
    transport = yield from self._make_subprocess_transport(
        protocol, popen_args, False, stdin, stdout, stderr,
        bufsize, **kwargs)
    if self._debug:
        logger.info('%s: %r' % (debug_log, transport))
    return transport, protocol

def subprocess_shell(

self, protocol_factory, cmd, **kwargs)

@coroutine
def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                     universal_newlines=False, shell=True, bufsize=0,
                     **kwargs):
    if not isinstance(cmd, (bytes, str)):
        raise ValueError("cmd must be a string")
    if universal_newlines:
        raise ValueError("universal_newlines must be False")
    if not shell:
        raise ValueError("shell must be True")
    if bufsize != 0:
        raise ValueError("bufsize must be 0")
    protocol = protocol_factory()
    if self._debug:
        # don't log parameters: they may contain sensitive information
        # (password) and may be too long
        debug_log = 'run shell command %r' % cmd
        self._log_subprocess(debug_log, stdin, stdout, stderr)
    transport = yield from self._make_subprocess_transport(
        protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs)
    if self._debug:
        logger.info('%s: %r' % (debug_log, transport))
    return transport, protocol

def time(

self)

Return the time according to the event loop's clock.

This is a float expressed in seconds since an epoch, but the epoch, precision, accuracy and drift are unspecified and may differ per event loop.

def time(self):
    """Return the time according to the event loop's clock.
    This is a float expressed in seconds since an epoch, but the
    epoch, precision, accuracy and drift are unspecified and may
    differ per event loop.
    """
    return time.monotonic()