💾 Archived View for tris.fyi › pydoc › linecache captured on 2023-01-29 at 03:21:20. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-07-16)

➡️ Next capture (2023-03-20)

🚧 View Differences

-=-=-=-=-=-=-

Back to module index

Go to module by name

linecache

Cache lines from Python source files.

This is intended to read lines from modules imported -- hence if a filename
is not found, it will look down the module search path for a file by
that name.

Functions

checkcache

checkcache(filename=None)

  Discard cache entries that are out of date.
      (This is not checked upon each call!)

clearcache

clearcache()

  Clear the cache entirely.

getline

getline(filename, lineno, module_globals=None)

  Get a line for a Python source file from the cache.
      Update the cache if it doesn't contain an entry for this file already.

getlines

getlines(filename, module_globals=None)

  Get the lines for a Python source file from the cache.
      Update the cache if it doesn't contain an entry for this file already.

lazycache

lazycache(filename, module_globals)

  Seed the cache for filename with module_globals.

      The module loader will be asked for the source only when getlines is
      called, not immediately.

      If there is an entry in the cache already, it is not altered.

      :return: True if a lazy load is registered in the cache,
          otherwise False. To register such a load a module loader with a
          get_source method must be found, the filename must be a cacheable
          filename, and the filename must not be already cached.
    

updatecache

updatecache(filename, module_globals=None)

  Update a cache entry and return its list of lines.
      If something's wrong, print a message, discard the cache entry,
      and return an empty list.

Other members

cache = {'/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/server.py': (2412, 1.0, ['#!/usr/bin/env python3\n', '\n', 'import asyncio\n', 'import logging\n', 'import signal\n', 'import traceback\n', 'from typing import TYPE_CHECKING\n', '\n', 'from .response import Response, Status\n', 'from .tls import make_sni_context\n', '\n', 'if TYPE_CHECKING:\n', '    from .config import Config\n', '\n', '\n', 'class Server:\n', '    def __init__(\n', '        self,\n', '        config: "Config",\n', '    ):\n', '        self.log = logging.getLogger("amethyst.server")\n', '        self.access_log = logging.getLogger("amethyst.access")\n', '\n', '        self.server = None\n', '        self.config = config\n', '\n', '        self.ssl_context = make_sni_context(config)\n', '        self.server = self.get_server()\n', '\n', '    def get_server(self):\n', '        loop = asyncio.get_event_loop()\n', '\n', '        return asyncio.start_server(\n', '            self.handle_connection,\n', '            port=self.config.port,\n', '            ssl=self.ssl_context,\n', '        )\n', '\n', '    async def handle_connection(self, reader, writer):\n', '        from .request import Connection\n', '\n', '        peer_addr = writer.get_extra_info("peername")\n', '        peer_cert = writer.get_extra_info("peercert")\n', '\n', '        self.log.debug(f"Received connection from {peer_addr}")\n', '\n', '        url = "-"\n', '        try:\n', '            url = (await reader.readuntil(b"\\r\\n")).rstrip(b"\\r\\n").decode()\n', '\n', '            if len(url) > 1024:\n', '                response = Response(Status.BAD_REQUEST, "URL too long!")\n', '            else:\n', '                response = await self.config.handler(\n', '                    url, Connection(self, peer_addr, peer_cert)\n', '                )\n', '\n', '        except UnicodeDecodeError:\n', '            response = Response(Status.BAD_REQUEST, "URL must be UTF-8")\n', '\n', '        except Exception:\n', '            self.log.error(f"While generating response; {traceback.format_exc()}")\n', '\n', '            response = Response(\n', '                Status.TEMPORARY_FAILURE,\n', '                "Exception thrown during request processing; see server logs for details.",\n', '            )\n', '\n', '        self.access_log.info(\n', '            f"{url} {response.status_code.value}[{response.status_code.name}]"\n', '            f" {response.meta}"\n', '        )\n', '\n', '        try:\n', '            line = f"{response.status_code.value} {response.meta}\\r\\n".encode()\n', '            writer.write(line)\n', '\n', '            if response.status_code.is_success() and response.content is not None:\n', '                writer.write(response.content)\n', '\n', '        except Exception:\n', '            self.log.error(f"While writing response; {traceback.format_exc()}")\n', '\n', '        finally:\n', '            writer.close()\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/server.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/handler.py': (2526, 1.0, ['from .resource import Resource\n', 'from .response import Status, Response\n', 'from .request import Connection, Context\n', 'from .util import get_path_components\n', 'from urllib.parse import urlparse\n', 'from typing import Dict, Callable, Awaitable\n', '\n', 'import logging\n', 'import re\n', '\n', 'Handler = Callable[[str, Connection], Awaitable[Response]]\n', 'PORT_RE = re.compile(r":([0-9]{1,5})$")\n', '\n', '\n', 'class GenericHandler:\n', '    def __init__(self, url_map: Dict[str, Dict[str, Resource]]):\n', '        self.url_map = url_map\n', '        self.log = logging.getLogger("amethyst.handler.GenericHandler")\n', '\n', '    async def __call__(self, url: str, conn: Connection) -> Response:\n', '        result = urlparse(url)\n', '\n', '        if not result.scheme:\n', '            return Response(Status.BAD_REQUEST, f"Requested URL must have a scheme.")\n', '\n', '        if result.scheme != "gemini":\n', '            # This is exclusively a Gemini server.\n', '            return Response(\n', '                Status.PROXY_REQUEST_REFUSED,\n', '                f"This server does not proxy non-Gemini URLs.",\n', '            )\n', '\n', '        host = result.netloc\n', '\n', '        if port_match := PORT_RE.search(host):\n', '            if int(port_match.group(1)) != conn.server.config.port:\n', '                return Response(\n', '                    Status.PROXY_REQUEST_REFUSED, f"{host} is not served here."\n', '                )\n', '\n', '            host = PORT_RE.sub("", host)\n', '\n', '        if host not in self.url_map:\n', '            self.log.warn(f"Received request for host {host} not in URL map")\n', '\n', '            return Response(\n', '                Status.PROXY_REQUEST_REFUSED,\n', '                f"{host} is not served here.",\n', '            )\n', '\n', '        req_path = result.path\n', '        try:\n', '            req_path = get_path_components(req_path)\n', '        except ValueError:\n', '            return Response(Status.BAD_REQUEST, "Invalid URL")\n', '\n', '        paths = [(get_path_components(i), v) for i, v in self.url_map[host].items()]\n', '\n', '        for path, resource in sorted(paths, key=lambda k: len(k[0]), reverse=True):\n', '            if len(req_path) < len(path) or req_path[: len(path)] != path:\n', '                continue\n', '\n', '            truncated_path = "/".join(req_path[len(path) :])\n', '            if result.path.endswith("/"):\n', '                truncated_path += "/"\n', '\n', '            return await resource(\n', '                Context(\n', '                    result.netloc,\n', '                    result.path,\n', '                    truncated_path,\n', '                    result.query,\n', '                    conn,\n', '                )\n', '            )\n', '\n', '        return Response(Status.NOT_FOUND, f"{req_path} was not found on this server.")\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/handler.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/resource.py': (5530, 1.0, ['import asyncio\n', 'import logging\n', 'import os\n', 'import os.path\n', 'import subprocess\n', '\n', 'from .mime import default_mime_types\n', 'from .response import Status, Response\n', 'from .request import Context\n', '\n', 'from typing import Callable, Awaitable\n', '\n', 'Resource = Callable[[Context], Awaitable[Response]]\n', '\n', '\n', 'class FilesystemResource:\n', '    def __init__(\n', '        self,\n', '        root,\n', '        autoindex=False,\n', '        cgi=False,\n', '        mime_types=None,\n', '        default_mime_type="application/octet-stream",\n', '    ):\n', '\n', '        self.log = logging.getLogger("amethyst.resource.FilesystemResource")\n', '        self.cgi_log = logging.getLogger("amethyst.resource.FilesystemResource.cgi")\n', '\n', '        self.autoindex = autoindex\n', '        self.cgi = cgi\n', '\n', '        self.index_files = ["index.gmi"]\n', '\n', '        self.mime_types = mime_types\n', '        if self.mime_types is None:\n', '            self.mime_types = default_mime_types\n', '\n', '        self.postprocessors = None\n', '        if self.postprocessors is None:\n', '            self.postprocessors = {}\n', '\n', '        self.default_mime_type = default_mime_type\n', '        self.root = os.path.abspath(root)\n', '\n', '    def send_file(self, filename: str) -> Response:\n', '        mime_type = self.default_mime_type\n', '        for ext in sorted(self.mime_types, key=len):\n', '            if filename.lower().endswith(ext.lower()):\n', '                mime_type = self.mime_types[ext]\n', '\n', '        with open(filename, "rb") as f:\n', '            contents = f.read()\n', '\n', '        self.log.debug(\n', '            f"Sending file {filename} ({len(contents)} bytes) as {mime_type}"\n', '        )\n', '\n', '        return Response(Status.SUCCESS, mime_type, contents)\n', '\n', '    async def do_cgi(self, ctx: Context, filename: str) -> Response:\n', '        # TODO: signal client certificates here\n', '        env = {\n', '            "GATEWAY_INTERFACE": "CGI/1.1",\n', '            "QUERY_STRING": ctx.query or "",\n', '            "REMOTE_ADDR": ctx.conn.peer_addr[0],\n', '            "SCRIPT_NAME": ctx.orig_path,\n', '            "SERVER_NAME": ctx.host,\n', '            "SERVER_PORT": str(ctx.conn.server.config.port),\n', '            "SERVER_PROTOCOL": "Gemini/0.16.0",\n', '            "SERVER_SOFTWARE": "Amethyst",\n', '        }\n', '\n', '        self.log.debug(f"Starting CGI script {filename}")\n', '\n', '        proc = await asyncio.create_subprocess_exec(\n', '            filename,\n', '            stdout=subprocess.PIPE,\n', '            stderr=subprocess.PIPE,\n', '            env=(os.environ | env),\n', '        )\n', '\n', '        stdout, stderr = await proc.communicate()\n', '\n', '        self.cgi_log.info(\n', '            f"{filename} returned {proc.returncode} "\n', '            f"(stdout bytes {len(stdout)}, "\n', '            f"stderr bytes {len(stderr)})"\n', '        )\n', '\n', '        if proc.returncode != 0:\n', '            return Response(Status.CGI_ERROR, f"Script returned {proc.returncode}")\n', '\n', '        content_type = "text/gemini"\n', '        status = Status.SUCCESS\n', '\n', '        lines = iter(stdout.split(b"\\n"))\n', '\n', '        for line in lines:\n', '            if not line or b":" not in line:\n', '                break\n', '\n', '            key, value = line.decode().strip().split(":", maxsplit=1)\n', '            key, value = key.strip().lower(), value.strip()\n', '\n', '            if key == "content-type":\n', '                content_type = value\n', '            elif key == "status":\n', '                try:\n', '                    status = Status(int(value))\n', '                except ValueError:\n', '                    pass\n', '            elif key == "location":\n', '                return Response(Status.REDIRECT_TEMPORARY, value)\n', '\n', '        result = b"\\n".join(lines)\n', '        if line:\n', '            result = line + b"\\n" + result\n', '\n', '        return Response(status, content_type, result)\n', '\n', '    async def __call__(self, ctx: Context) -> Response:\n', '        full_path = os.path.abspath(os.path.join(self.root, ctx.path.lstrip("/")))\n', '\n', '        if os.path.isdir(full_path):\n', '            if not (full_path + os.sep).startswith(self.root + os.sep):\n', '                self.log.warn(f"Tried to handle from disallowed path {full_path}!")\n', '                return Response(Status.BAD_REQUEST, "Invalid path")\n', '\n', '            for filename in self.index_files:\n', '                filename = os.path.join(full_path, filename)\n', '                if os.path.exists(filename):\n', '                    self.log.debug(\n', '                        f"Sending index file {filename} for request to {ctx.orig_path}"\n', '                    )\n', '                    return self.send_file(filename)\n', '\n', '            if self.autoindex:\n', '                self.log.debug(\n', '                    f"Performing directory listing of {full_path} for request to {ctx.orig_path}"\n', '                )\n', '\n', '                lines = [f"# Directory listing of {ctx.orig_path}", ""]\n', '\n', '                for filename in sorted(os.listdir(full_path)):\n', '                    if os.path.isdir(os.path.join(full_path, filename)):\n', '                        lines.append(f"=> {filename}/")\n', '                    else:\n', '                        lines.append(f"=> {filename}")\n', '\n', '                listing = "\\n".join(lines).encode()\n', '                return Response(Status.SUCCESS, "text/gemini", listing)\n', '\n', '        elif os.path.isfile(full_path):\n', '            if full_path != self.root and not full_path.startswith(self.root + os.sep):\n', '                self.log.warn(f"Tried to handle from disallowed path {full_path}!")\n', '                return Response(Status.BAD_REQUEST, "Invalid path")\n', '\n', '            if self.cgi and os.access(full_path, os.X_OK):\n', '                return await self.do_cgi(ctx, full_path)\n', '\n', '            return self.send_file(full_path)\n', '\n', '        self.log.debug("{full_path} not found")\n', '        return Response(\n', '            Status.NOT_FOUND, f"{ctx.orig_path} was not found on this server."\n', '        )\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/resource.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/subprocess.py': (7405, 1.0, ["__all__ = 'create_subprocess_exec', 'create_subprocess_shell'\n", '\n', 'import subprocess\n', '\n', 'from . import events\n', 'from . import protocols\n', 'from . import streams\n', 'from . import tasks\n', 'from .log import logger\n', '\n', '\n', 'PIPE = subprocess.PIPE\n', 'STDOUT = subprocess.STDOUT\n', 'DEVNULL = subprocess.DEVNULL\n', '\n', '\n', 'class SubprocessStreamProtocol(streams.FlowControlMixin,\n', '                               protocols.SubprocessProtocol):\n', '    """Like StreamReaderProtocol, but for a subprocess."""\n', '\n', '    def __init__(self, limit, loop):\n', '        super().__init__(loop=loop)\n', '        self._limit = limit\n', '        self.stdin = self.stdout = self.stderr = None\n', '        self._transport = None\n', '        self._process_exited = False\n', '        self._pipe_fds = []\n', '        self._stdin_closed = self._loop.create_future()\n', '\n', '    def __repr__(self):\n', '        info = [self.__class__.__name__]\n', '        if self.stdin is not None:\n', "            info.append(f'stdin={self.stdin!r}')\n", '        if self.stdout is not None:\n', "            info.append(f'stdout={self.stdout!r}')\n", '        if self.stderr is not None:\n', "            info.append(f'stderr={self.stderr!r}')\n", "        return '<{}>'.format(' '.join(info))\n", '\n', '    def connection_made(self, transport):\n', '        self._transport = transport\n', '\n', '        stdout_transport = transport.get_pipe_transport(1)\n', '        if stdout_transport is not None:\n', '            self.stdout = streams.StreamReader(limit=self._limit,\n', '                                               loop=self._loop)\n', '            self.stdout.set_transport(stdout_transport)\n', '            self._pipe_fds.append(1)\n', '\n', '        stderr_transport = transport.get_pipe_transport(2)\n', '        if stderr_transport is not None:\n', '            self.stderr = streams.StreamReader(limit=self._limit,\n', '                                               loop=self._loop)\n', '            self.stderr.set_transport(stderr_transport)\n', '            self._pipe_fds.append(2)\n', '\n', '        stdin_transport = transport.get_pipe_transport(0)\n', '        if stdin_transport is not None:\n', '            self.stdin = streams.StreamWriter(stdin_transport,\n', '                                              protocol=self,\n', '                                              reader=None,\n', '                                              loop=self._loop)\n', '\n', '    def pipe_data_received(self, fd, data):\n', '        if fd == 1:\n', '            reader = self.stdout\n', '        elif fd == 2:\n', '            reader = self.stderr\n', '        else:\n', '            reader = None\n', '        if reader is not None:\n', '            reader.feed_data(data)\n', '\n', '    def pipe_connection_lost(self, fd, exc):\n', '        if fd == 0:\n', '            pipe = self.stdin\n', '            if pipe is not None:\n', '                pipe.close()\n', '            self.connection_lost(exc)\n', '            if exc is None:\n', '                self._stdin_closed.set_result(None)\n', '            else:\n', '                self._stdin_closed.set_exception(exc)\n', '            return\n', '        if fd == 1:\n', '            reader = self.stdout\n', '        elif fd == 2:\n', '            reader = self.stderr\n', '        else:\n', '            reader = None\n', '        if reader is not None:\n', '            if exc is None:\n', '                reader.feed_eof()\n', '            else:\n', '                reader.set_exception(exc)\n', '\n', '        if fd in self._pipe_fds:\n', '            self._pipe_fds.remove(fd)\n', '        self._maybe_close_transport()\n', '\n', '    def process_exited(self):\n', '        self._process_exited = True\n', '        self._maybe_close_transport()\n', '\n', '    def _maybe_close_transport(self):\n', '        if len(self._pipe_fds) == 0 and self._process_exited:\n', '            self._transport.close()\n', '            self._transport = None\n', '\n', '    def _get_close_waiter(self, stream):\n', '        if stream is self.stdin:\n', '            return self._stdin_closed\n', '\n', '\n', 'class Process:\n', '    def __init__(self, transport, protocol, loop):\n', '        self._transport = transport\n', '        self._protocol = protocol\n', '        self._loop = loop\n', '        self.stdin = protocol.stdin\n', '        self.stdout = protocol.stdout\n', '        self.stderr = protocol.stderr\n', '        self.pid = transport.get_pid()\n', '\n', '    def __repr__(self):\n', "        return f'<{self.__class__.__name__} {self.pid}>'\n", '\n', '    @property\n', '    def returncode(self):\n', '        return self._transport.get_returncode()\n', '\n', '    async def wait(self):\n', '        """Wait until the process exit and return the process return code."""\n', '        return await self._transport._wait()\n', '\n', '    def send_signal(self, signal):\n', '        self._transport.send_signal(signal)\n', '\n', '    def terminate(self):\n', '        self._transport.terminate()\n', '\n', '    def kill(self):\n', '        self._transport.kill()\n', '\n', '    async def _feed_stdin(self, input):\n', '        debug = self._loop.get_debug()\n', '        self.stdin.write(input)\n', '        if debug:\n', '            logger.debug(\n', "                '%r communicate: feed stdin (%s bytes)', self, len(input))\n", '        try:\n', '            await self.stdin.drain()\n', '        except (BrokenPipeError, ConnectionResetError) as exc:\n', '            # communicate() ignores BrokenPipeError and ConnectionResetError\n', '            if debug:\n', "                logger.debug('%r communicate: stdin got %r', self, exc)\n", '\n', '        if debug:\n', "            logger.debug('%r communicate: close stdin', self)\n", '        self.stdin.close()\n', '\n', '    async def _noop(self):\n', '        return None\n', '\n', '    async def _read_stream(self, fd):\n', '        transport = self._transport.get_pipe_transport(fd)\n', '        if fd == 2:\n', '            stream = self.stderr\n', '        else:\n', '            assert fd == 1\n', '            stream = self.stdout\n', '        if self._loop.get_debug():\n', "            name = 'stdout' if fd == 1 else 'stderr'\n", "            logger.debug('%r communicate: read %s', self, name)\n", '        output = await stream.read()\n', '        if self._loop.get_debug():\n', "            name = 'stdout' if fd == 1 else 'stderr'\n", "            logger.debug('%r communicate: close %s', self, name)\n", '        transport.close()\n', '        return output\n', '\n', '    async def communicate(self, input=None):\n', '        if input is not None:\n', '            stdin = self._feed_stdin(input)\n', '        else:\n', '            stdin = self._noop()\n', '        if self.stdout is not None:\n', '            stdout = self._read_stream(1)\n', '        else:\n', '            stdout = self._noop()\n', '        if self.stderr is not None:\n', '            stderr = self._read_stream(2)\n', '        else:\n', '            stderr = self._noop()\n', '        stdin, stdout, stderr = await tasks.gather(stdin, stdout, stderr)\n', '        await self.wait()\n', '        return (stdout, stderr)\n', '\n', '\n', 'async def create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None,\n', '                                  limit=streams._DEFAULT_LIMIT, **kwds):\n', '    loop = events.get_running_loop()\n', '    protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,\n', '                                                        loop=loop)\n', '    transport, protocol = await loop.subprocess_shell(\n', '        protocol_factory,\n', '        cmd, stdin=stdin, stdout=stdout,\n', '        stderr=stderr, **kwds)\n', '    return Process(transport, protocol, loop)\n', '\n', '\n', 'async def create_subprocess_exec(program, *args, stdin=None, stdout=None,\n', '                                 stderr=None, limit=streams._DEFAULT_LIMIT,\n', '                                 **kwds):\n', '    loop = events.get_running_loop()\n', '    protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,\n', '                                                        loop=loop)\n', '    transport, protocol = await loop.subprocess_exec(\n', '        protocol_factory,\n', '        program, *args,\n', '        stdin=stdin, stdout=stdout,\n', '        stderr=stderr, **kwds)\n', '    return Process(transport, protocol, loop)\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/subprocess.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/base_events.py': (73939, 1.0, ['"""Base implementation of event loop.\n', '\n', 'The event loop can be broken up into a multiplexer (the part\n', 'responsible for notifying us of I/O events) and the event loop proper,\n', 'which wraps a multiplexer with functionality for scheduling callbacks,\n', 'immediately or at a given time in the future.\n', '\n', 'Whenever a public API takes a callback, subsequent positional\n', 'arguments will be passed to the callback if/when it is called.  This\n', 'avoids the proliferation of trivial lambdas implementing closures.\n', 'Keyword arguments for the callback are not supported; this is a\n', 'conscious design decision, leaving the door open for keyword arguments\n', 'to modify the meaning of the API call itself.\n', '"""\n', '\n', 'import collections\n', 'import collections.abc\n', 'import concurrent.futures\n', 'import functools\n', 'import heapq\n', 'import itertools\n', 'import os\n', 'import socket\n', 'import stat\n', 'import subprocess\n', 'import threading\n', 'import time\n', 'import traceback\n', 'import sys\n', 'import warnings\n', 'import weakref\n', '\n', 'try:\n', '    import ssl\n', 'except ImportError:  # pragma: no cover\n', '    ssl = None\n', '\n', 'from . import constants\n', 'from . import coroutines\n', 'from . import events\n', 'from . import exceptions\n', 'from . import futures\n', 'from . import protocols\n', 'from . import sslproto\n', 'from . import staggered\n', 'from . import tasks\n', 'from . import transports\n', 'from . import trsock\n', 'from .log import logger\n', '\n', '\n', "__all__ = 'BaseEventLoop','Server',\n", '\n', '\n', '# Minimum number of _scheduled timer handles before cleanup of\n', '# cancelled handles is performed.\n', '_MIN_SCHEDULED_TIMER_HANDLES = 100\n', '\n', '# Minimum fraction of _scheduled timer handles that are cancelled\n', '# before cleanup of cancelled handles is performed.\n', '_MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5\n', '\n', '\n', "_HAS_IPv6 = hasattr(socket, 'AF_INET6')\n", '\n', '# Maximum timeout passed to select to avoid OS limitations\n', 'MAXIMUM_SELECT_TIMEOUT = 24 * 3600\n', '\n', "# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s\n", '# *reuse_address* parameter\n', '_unset = object()\n', '\n', '\n', 'def _format_handle(handle):\n', '    cb = handle._callback\n', "    if isinstance(getattr(cb, '__self__', None), tasks.Task):\n", '        # format the task\n', '        return repr(cb.__self__)\n', '    else:\n', '        return str(handle)\n', '\n', '\n', 'def _format_pipe(fd):\n', '    if fd == subprocess.PIPE:\n', "        return '<pipe>'\n", '    elif fd == subprocess.STDOUT:\n', "        return '<stdout>'\n", '    else:\n', '        return repr(fd)\n', '\n', '\n', 'def _set_reuseport(sock):\n', "    if not hasattr(socket, 'SO_REUSEPORT'):\n", "        raise ValueError('reuse_port not supported by socket module')\n", '    else:\n', '        try:\n', '            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)\n', '        except OSError:\n', "            raise ValueError('reuse_port not supported by socket module, '\n", "                             'SO_REUSEPORT defined but not implemented.')\n", '\n', '\n', 'def _ipaddr_info(host, port, family, type, proto, flowinfo=0, scopeid=0):\n', '    # Try to skip getaddrinfo if "host" is already an IP. Users might have\n', '    # handled name resolution in their own code and pass in resolved IPs.\n', "    if not hasattr(socket, 'inet_pton'):\n", '        return\n', '\n', '    if proto not in {0, socket.IPPROTO_TCP, socket.IPPROTO_UDP} or \\\n', '            host is None:\n', '        return None\n', '\n', '    if type == socket.SOCK_STREAM:\n', '        proto = socket.IPPROTO_TCP\n', '    elif type == socket.SOCK_DGRAM:\n', '        proto = socket.IPPROTO_UDP\n', '    else:\n', '        return None\n', '\n', '    if port is None:\n', '        port = 0\n', "    elif isinstance(port, bytes) and port == b'':\n", '        port = 0\n', "    elif isinstance(port, str) and port == '':\n", '        port = 0\n', '    else:\n', '        # If port\'s a service name like "http", don\'t skip getaddrinfo.\n', '        try:\n', '            port = int(port)\n', '        except (TypeError, ValueError):\n', '            return None\n', '\n', '    if family == socket.AF_UNSPEC:\n', '        afs = [socket.AF_INET]\n', '        if _HAS_IPv6:\n', '            afs.append(socket.AF_INET6)\n', '    else:\n', '        afs = [family]\n', '\n', '    if isinstance(host, bytes):\n', "        host = host.decode('idna')\n", "    if '%' in host:\n", "        # Linux's inet_pton doesn't accept an IPv6 zone index after host,\n", "        # like '::1%lo0'.\n", '        return None\n', '\n', '    for af in afs:\n', '        try:\n', '            socket.inet_pton(af, host)\n', '            # The host has already been resolved.\n', '            if _HAS_IPv6 and af == socket.AF_INET6:\n', "                return af, type, proto, '', (host, port, flowinfo, scopeid)\n", '            else:\n', "                return af, type, proto, '', (host, port)\n", '        except OSError:\n', '            pass\n', '\n', '    # "host" is not an IP address.\n', '    return None\n', '\n', '\n', 'def _interleave_addrinfos(addrinfos, first_address_family_count=1):\n', '    """Interleave list of addrinfo tuples by family."""\n', '    # Group addresses by family\n', '    addrinfos_by_family = collections.OrderedDict()\n', '    for addr in addrinfos:\n', '        family = addr[0]\n', '        if family not in addrinfos_by_family:\n', '            addrinfos_by_family[family] = []\n', '        addrinfos_by_family[family].append(addr)\n', '    addrinfos_lists = list(addrinfos_by_family.values())\n', '\n', '    reordered = []\n', '    if first_address_family_count > 1:\n', '        reordered.extend(addrinfos_lists[0][:first_address_family_count - 1])\n', '        del addrinfos_lists[0][:first_address_family_count - 1]\n', '    reordered.extend(\n', '        a for a in itertools.chain.from_iterable(\n', '            itertools.zip_longest(*addrinfos_lists)\n', '        ) if a is not None)\n', '    return reordered\n', '\n', '\n', 'def _run_until_complete_cb(fut):\n', '    if not fut.cancelled():\n', '        exc = fut.exception()\n', '        if isinstance(exc, (SystemExit, KeyboardInterrupt)):\n', '            # Issue #22429: run_forever() already finished, no need to\n', '            # stop it.\n', '            return\n', '    futures._get_loop(fut).stop()\n', '\n', '\n', "if hasattr(socket, 'TCP_NODELAY'):\n", '    def _set_nodelay(sock):\n', '        if (sock.family in {socket.AF_INET, socket.AF_INET6} and\n', '                sock.type == socket.SOCK_STREAM and\n', '                sock.proto == socket.IPPROTO_TCP):\n', '            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n', 'else:\n', '    def _set_nodelay(sock):\n', '        pass\n', '\n', '\n', 'def _check_ssl_socket(sock):\n', '    if ssl is not None and isinstance(sock, ssl.SSLSocket):\n', '        raise TypeError("Socket cannot be of type SSLSocket")\n', '\n', '\n', 'class _SendfileFallbackProtocol(protocols.Protocol):\n', '    def __init__(self, transp):\n', '        if not isinstance(transp, transports._FlowControlMixin):\n', '            raise TypeError("transport should be _FlowControlMixin instance")\n', '        self._transport = transp\n', '        self._proto = transp.get_protocol()\n', '        self._should_resume_reading = transp.is_reading()\n', '        self._should_resume_writing = transp._protocol_paused\n', '        transp.pause_reading()\n', '        transp.set_protocol(self)\n', '        if self._should_resume_writing:\n', '            self._write_ready_fut = self._transport._loop.create_future()\n', '        else:\n', '            self._write_ready_fut = None\n', '\n', '    async def drain(self):\n', '        if self._transport.is_closing():\n', '            raise ConnectionError("Connection closed by peer")\n', '        fut = self._write_ready_fut\n', '        if fut is None:\n', '            return\n', '        await fut\n', '\n', '    def connection_made(self, transport):\n', '        raise RuntimeError("Invalid state: "\n', '                           "connection should have been established already.")\n', '\n', '    def connection_lost(self, exc):\n', '        if self._write_ready_fut is not None:\n', '            # Never happens if peer disconnects after sending the whole content\n', '            # Thus disconnection is always an exception from user perspective\n', '            if exc is None:\n', '                self._write_ready_fut.set_exception(\n', '                    ConnectionError("Connection is closed by peer"))\n', '            else:\n', '                self._write_ready_fut.set_exception(exc)\n', '        self._proto.connection_lost(exc)\n', '\n', '    def pause_writing(self):\n', '        if self._write_ready_fut is not None:\n', '            return\n', '        self._write_ready_fut = self._transport._loop.create_future()\n', '\n', '    def resume_writing(self):\n', '        if self._write_ready_fut is None:\n', '            return\n', '        self._write_ready_fut.set_result(False)\n', '        self._write_ready_fut = None\n', '\n', '    def data_received(self, data):\n', '        raise RuntimeError("Invalid state: reading should be paused")\n', '\n', '    def eof_received(self):\n', '        raise RuntimeError("Invalid state: reading should be paused")\n', '\n', '    async def restore(self):\n', '        self._transport.set_protocol(self._proto)\n', '        if self._should_resume_reading:\n', '            self._transport.resume_reading()\n', '        if self._write_ready_fut is not None:\n', '            # Cancel the future.\n', '            # Basically it has no effect because protocol is switched back,\n', '            # no code should wait for it anymore.\n', '            self._write_ready_fut.cancel()\n', '        if self._should_resume_writing:\n', '            self._proto.resume_writing()\n', '\n', '\n', 'class Server(events.AbstractServer):\n', '\n', '    def __init__(self, loop, sockets, protocol_factory, ssl_context, backlog,\n', '                 ssl_handshake_timeout):\n', '        self._loop = loop\n', '        self._sockets = sockets\n', '        self._active_count = 0\n', '        self._waiters = []\n', '        self._protocol_factory = protocol_factory\n', '        self._backlog = backlog\n', '        self._ssl_context = ssl_context\n', '        self._ssl_handshake_timeout = ssl_handshake_timeout\n', '        self._serving = False\n', '        self._serving_forever_fut = None\n', '\n', '    def __repr__(self):\n', "        return f'<{self.__class__.__name__} sockets={self.sockets!r}>'\n", '\n', '    def _attach(self):\n', '        assert self._sockets is not None\n', '        self._active_count += 1\n', '\n', '    def _detach(self):\n', '        assert self._active_count > 0\n', '        self._active_count -= 1\n', '        if self._active_count == 0 and self._sockets is None:\n', '            self._wakeup()\n', '\n', '    def _wakeup(self):\n', '        waiters = self._waiters\n', '        self._waiters = None\n', '        for waiter in waiters:\n', '            if not waiter.done():\n', '                waiter.set_result(waiter)\n', '\n', '    def _start_serving(self):\n', '        if self._serving:\n', '            return\n', '        self._serving = True\n', '        for sock in self._sockets:\n', '            sock.listen(self._backlog)\n', '            self._loop._start_serving(\n', '                self._protocol_factory, sock, self._ssl_context,\n', '                self, self._backlog, self._ssl_handshake_timeout)\n', '\n', '    def get_loop(self):\n', '        return self._loop\n', '\n', '    def is_serving(self):\n', '        return self._serving\n', '\n', '    @property\n', '    def sockets(self):\n', '        if self._sockets is None:\n', '            return ()\n', '        return tuple(trsock.TransportSocket(s) for s in self._sockets)\n', '\n', '    def close(self):\n', '        sockets = self._sockets\n', '        if sockets is None:\n', '            return\n', '        self._sockets = None\n', '\n', '        for sock in sockets:\n', '            self._loop._stop_serving(sock)\n', '\n', '        self._serving = False\n', '\n', '        if (self._serving_forever_fut is not None and\n', '                not self._serving_forever_fut.done()):\n', '            self._serving_forever_fut.cancel()\n', '            self._serving_forever_fut = None\n', '\n', '        if self._active_count == 0:\n', '            self._wakeup()\n', '\n', '    async def start_serving(self):\n', '        self._start_serving()\n', "        # Skip one loop iteration so that all 'loop.add_reader'\n", '        # go through.\n', '        await tasks.sleep(0)\n', '\n', '    async def serve_forever(self):\n', '        if self._serving_forever_fut is not None:\n', '            raise RuntimeError(\n', "                f'server {self!r} is already being awaited on serve_forever()')\n", '        if self._sockets is None:\n', "            raise RuntimeError(f'server {self!r} is closed')\n", '\n', '        self._start_serving()\n', '        self._serving_forever_fut = self._loop.create_future()\n', '\n', '        try:\n', '            await self._serving_forever_fut\n', '        except exceptions.CancelledError:\n', '            try:\n', '                self.close()\n', '                await self.wait_closed()\n', '            finally:\n', '                raise\n', '        finally:\n', '            self._serving_forever_fut = None\n', '\n', '    async def wait_closed(self):\n', '        if self._sockets is None or self._waiters is None:\n', '            return\n', '        waiter = self._loop.create_future()\n', '        self._waiters.append(waiter)\n', '        await waiter\n', '\n', '\n', 'class BaseEventLoop(events.AbstractEventLoop):\n', '\n', '    def __init__(self):\n', '        self._timer_cancelled_count = 0\n', '        self._closed = False\n', '        self._stopping = False\n', '        self._ready = collections.deque()\n', '        self._scheduled = []\n', '        self._default_executor = None\n', '        self._internal_fds = 0\n', '        # Identifier of the thread running the event loop, or None if the\n', '        # event loop is not running\n', '        self._thread_id = None\n', "        self._clock_resolution = time.get_clock_info('monotonic').resolution\n", '        self._exception_handler = None\n', '        self.set_debug(coroutines._is_debug_mode())\n', '        # In debug mode, if the execution of a callback or a step of a task\n', '        # exceed this duration in seconds, the slow callback/task is logged.\n', '        self.slow_callback_duration = 0.1\n', '        self._current_handle = None\n', '        self._task_factory = None\n', '        self._coroutine_origin_tracking_enabled = False\n', '        self._coroutine_origin_tracking_saved_depth = None\n', '\n', '        # A weak set of all asynchronous generators that are\n', '        # being iterated by the loop.\n', '        self._asyncgens = weakref.WeakSet()\n', '        # Set to True when `loop.shutdown_asyncgens` is called.\n', '        self._asyncgens_shutdown_called = False\n', '        # Set to True when `loop.shutdown_default_executor` is called.\n', '        self._executor_shutdown_called = False\n', '\n', '    def __repr__(self):\n', '        return (\n', "            f'<{self.__class__.__name__} running={self.is_running()} '\n", "            f'closed={self.is_closed()} debug={self.get_debug()}>'\n", '        )\n', '\n', '    def create_future(self):\n', '        """Create a Future object attached to the loop."""\n', '        return futures.Future(loop=self)\n', '\n', '    def create_task(self, coro, *, name=None):\n', '        """Schedule a coroutine object.\n', '\n', '        Return a task object.\n', '        """\n', '        self._check_closed()\n', '        if self._task_factory is None:\n', '            task = tasks.Task(coro, loop=self, name=name)\n', '            if task._source_traceback:\n', '                del task._source_traceback[-1]\n', '        else:\n', '            task = self._task_factory(self, coro)\n', '            tasks._set_task_name(task, name)\n', '\n', '        return task\n', '\n', '    def set_task_factory(self, factory):\n', '        """Set a task factory that will be used by loop.create_task().\n', '\n', '        If factory is None the default task factory will be set.\n', '\n', '        If factory is a callable, it should have a signature matching\n', "        '(loop, coro)', where 'loop' will be a reference to the active\n", "        event loop, 'coro' will be a coroutine object.  The callable\n", '        must return a Future.\n', '        """\n', '        if factory is not None and not callable(factory):\n', "            raise TypeError('task factory must be a callable or None')\n", '        self._task_factory = factory\n', '\n', '    def get_task_factory(self):\n', '        """Return a task factory, or None if the default one is in use."""\n', '        return self._task_factory\n', '\n', '    def _make_socket_transport(self, sock, protocol, waiter=None, *,\n', '                               extra=None, server=None):\n', '        """Create socket transport."""\n', '        raise NotImplementedError\n', '\n', '    def _make_ssl_transport(\n', '            self, rawsock, protocol, sslcontext, waiter=None,\n', '            *, server_side=False, server_hostname=None,\n', '            extra=None, server=None,\n', '            ssl_handshake_timeout=None,\n', '            call_connection_made=True):\n', '        """Create SSL transport."""\n', '        raise NotImplementedError\n', '\n', '    def _make_datagram_transport(self, sock, protocol,\n', '                                 address=None, waiter=None, extra=None):\n', '        """Create datagram transport."""\n', '        raise NotImplementedError\n', '\n', '    def _make_read_pipe_transport(self, pipe, protocol, waiter=None,\n', '                                  extra=None):\n', '        """Create read pipe transport."""\n', '        raise NotImplementedError\n', '\n', '    def _make_write_pipe_transport(self, pipe, protocol, waiter=None,\n', '                                   extra=None):\n', '        """Create write pipe transport."""\n', '        raise NotImplementedError\n', '\n', '    async def _make_subprocess_transport(self, protocol, args, shell,\n', '                                         stdin, stdout, stderr, bufsize,\n', '                                         extra=None, **kwargs):\n', '        """Create subprocess transport."""\n', '        raise NotImplementedError\n', '\n', '    def _write_to_self(self):\n', '        """Write a byte to self-pipe, to wake up the event loop.\n', '\n', '        This may be called from a different thread.\n', '\n', '        The subclass is responsible for implementing the self-pipe.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    def _process_events(self, event_list):\n', '        """Process selector events."""\n', '        raise NotImplementedError\n', '\n', '    def _check_closed(self):\n', '        if self._closed:\n', "            raise RuntimeError('Event loop is closed')\n", '\n', '    def _check_default_executor(self):\n', '        if self._executor_shutdown_called:\n', "            raise RuntimeError('Executor shutdown has been called')\n", '\n', '    def _asyncgen_finalizer_hook(self, agen):\n', '        self._asyncgens.discard(agen)\n', '        if not self.is_closed():\n', '            self.call_soon_threadsafe(self.create_task, agen.aclose())\n', '\n', '    def _asyncgen_firstiter_hook(self, agen):\n', '        if self._asyncgens_shutdown_called:\n', '            warnings.warn(\n', '                f"asynchronous generator {agen!r} was scheduled after "\n', '                f"loop.shutdown_asyncgens() call",\n', '                ResourceWarning, source=self)\n', '\n', '        self._asyncgens.add(agen)\n', '\n', '    async def shutdown_asyncgens(self):\n', '        """Shutdown all active asynchronous generators."""\n', '        self._asyncgens_shutdown_called = True\n', '\n', '        if not len(self._asyncgens):\n', "            # If Python version is <3.6 or we don't have any asynchronous\n", '            # generators alive.\n', '            return\n', '\n', '        closing_agens = list(self._asyncgens)\n', '        self._asyncgens.clear()\n', '\n', '        results = await tasks.gather(\n', '            *[ag.aclose() for ag in closing_agens],\n', '            return_exceptions=True)\n', '\n', '        for result, agen in zip(results, closing_agens):\n', '            if isinstance(result, Exception):\n', '                self.call_exception_handler({\n', "                    'message': f'an error occurred during closing of '\n", "                               f'asynchronous generator {agen!r}',\n", "                    'exception': result,\n", "                    'asyncgen': agen\n", '                })\n', '\n', '    async def shutdown_default_executor(self):\n', '        """Schedule the shutdown of the default executor."""\n', '        self._executor_shutdown_called = True\n', '        if self._default_executor is None:\n', '            return\n', '        future = self.create_future()\n', '        thread = threading.Thread(target=self._do_shutdown, args=(future,))\n', '        thread.start()\n', '        try:\n', '            await future\n', '        finally:\n', '            thread.join()\n', '\n', '    def _do_shutdown(self, future):\n', '        try:\n', '            self._default_executor.shutdown(wait=True)\n', '            if not self.is_closed():\n', '                self.call_soon_threadsafe(future.set_result, None)\n', '        except Exception as ex:\n', '            if not self.is_closed():\n', '                self.call_soon_threadsafe(future.set_exception, ex)\n', '\n', '    def _check_running(self):\n', '        if self.is_running():\n', "            raise RuntimeError('This event loop is already running')\n", '        if events._get_running_loop() is not None:\n', '            raise RuntimeError(\n', "                'Cannot run the event loop while another loop is running')\n", '\n', '    def run_forever(self):\n', '        """Run until stop() is called."""\n', '        self._check_closed()\n', '        self._check_running()\n', '        self._set_coroutine_origin_tracking(self._debug)\n', '\n', '        old_agen_hooks = sys.get_asyncgen_hooks()\n', '        try:\n', '            self._thread_id = threading.get_ident()\n', '            sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,\n', '                                   finalizer=self._asyncgen_finalizer_hook)\n', '\n', '            events._set_running_loop(self)\n', '            while True:\n', '                self._run_once()\n', '                if self._stopping:\n', '                    break\n', '        finally:\n', '            self._stopping = False\n', '            self._thread_id = None\n', '            events._set_running_loop(None)\n', '            self._set_coroutine_origin_tracking(False)\n', '            sys.set_asyncgen_hooks(*old_agen_hooks)\n', '\n', '    def run_until_complete(self, future):\n', '        """Run until the Future is done.\n', '\n', '        If the argument is a coroutine, it is wrapped in a Task.\n', '\n', '        WARNING: It would be disastrous to call run_until_complete()\n', '        with the same coroutine twice -- it would wrap it in two\n', "        different Tasks and that can't be good.\n", '\n', "        Return the Future's result, or raise its exception.\n", '        """\n', '        self._check_closed()\n', '        self._check_running()\n', '\n', '        new_task = not futures.isfuture(future)\n', '        future = tasks.ensure_future(future, loop=self)\n', '        if new_task:\n', "            # An exception is raised if the future didn't complete, so there\n", '            # is no need to log the "destroy pending task" message\n', '            future._log_destroy_pending = False\n', '\n', '        future.add_done_callback(_run_until_complete_cb)\n', '        try:\n', '            self.run_forever()\n', '        except:\n', '            if new_task and future.done() and not future.cancelled():\n', '                # The coroutine raised a BaseException. Consume the exception\n', "                # to not log a warning, the caller doesn't have access to the\n", '                # local task.\n', '                future.exception()\n', '            raise\n', '        finally:\n', '            future.remove_done_callback(_run_until_complete_cb)\n', '        if not future.done():\n', "            raise RuntimeError('Event loop stopped before Future completed.')\n", '\n', '        return future.result()\n', '\n', '    def stop(self):\n', '        """Stop running the event loop.\n', '\n', '        Every callback already scheduled will still run.  This simply informs\n', '        run_forever to stop looping after a complete iteration.\n', '        """\n', '        self._stopping = True\n', '\n', '    def close(self):\n', '        """Close the event loop.\n', '\n', '        This clears the queues and shuts down the executor,\n', '        but does not wait for the executor to finish.\n', '\n', '        The event loop must not be running.\n', '        """\n', '        if self.is_running():\n', '            raise RuntimeError("Cannot close a running event loop")\n', '        if self._closed:\n', '            return\n', '        if self._debug:\n', '            logger.debug("Close %r", self)\n', '        self._closed = True\n', '        self._ready.clear()\n', '        self._scheduled.clear()\n', '        self._executor_shutdown_called = True\n', '        executor = self._default_executor\n', '        if executor is not None:\n', '            self._default_executor = None\n', '            executor.shutdown(wait=False)\n', '\n', '    def is_closed(self):\n', '        """Returns True if the event loop was closed."""\n', '        return self._closed\n', '\n', '    def __del__(self, _warn=warnings.warn):\n', '        if not self.is_closed():\n', '            _warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)\n', '            if not self.is_running():\n', '                self.close()\n', '\n', '    def is_running(self):\n', '        """Returns True if the event loop is running."""\n', '        return (self._thread_id is not None)\n', '\n', '    def time(self):\n', '        """Return the time according to the event loop\'s clock.\n', '\n', '        This is a float expressed in seconds since an epoch, but the\n', '        epoch, precision, accuracy and drift are unspecified and may\n', '        differ per event loop.\n', '        """\n', '        return time.monotonic()\n', '\n', '    def call_later(self, delay, callback, *args, context=None):\n', '        """Arrange for a callback to be called at a given time.\n', '\n', '        Return a Handle: an opaque object with a cancel() method that\n', '        can be used to cancel the call.\n', '\n', '        The delay can be an int or float, expressed in seconds.  It is\n', '        always relative to the current time.\n', '\n', '        Each callback will be called exactly once.  If two callbacks\n', '        are scheduled for exactly the same time, it undefined which\n', '        will be called first.\n', '\n', '        Any positional arguments after the callback will be passed to\n', '        the callback when it is called.\n', '        """\n', '        timer = self.call_at(self.time() + delay, callback, *args,\n', '                             context=context)\n', '        if timer._source_traceback:\n', '            del timer._source_traceback[-1]\n', '        return timer\n', '\n', '    def call_at(self, when, callback, *args, context=None):\n', '        """Like call_later(), but uses an absolute time.\n', '\n', "        Absolute time corresponds to the event loop's time() method.\n", '        """\n', '        self._check_closed()\n', '        if self._debug:\n', '            self._check_thread()\n', "            self._check_callback(callback, 'call_at')\n", '        timer = events.TimerHandle(when, callback, args, self, context)\n', '        if timer._source_traceback:\n', '            del timer._source_traceback[-1]\n', '        heapq.heappush(self._scheduled, timer)\n', '        timer._scheduled = True\n', '        return timer\n', '\n', '    def call_soon(self, callback, *args, context=None):\n', '        """Arrange for a callback to be called as soon as possible.\n', '\n', '        This operates as a FIFO queue: callbacks are called in the\n', '        order in which they are registered.  Each callback will be\n', '        called exactly once.\n', '\n', '        Any positional arguments after the callback will be passed to\n', '        the callback when it is called.\n', '        """\n', '        self._check_closed()\n', '        if self._debug:\n', '            self._check_thread()\n', "            self._check_callback(callback, 'call_soon')\n", '        handle = self._call_soon(callback, args, context)\n', '        if handle._source_traceback:\n', '            del handle._source_traceback[-1]\n', '        return handle\n', '\n', '    def _check_callback(self, callback, method):\n', '        if (coroutines.iscoroutine(callback) or\n', '                coroutines.iscoroutinefunction(callback)):\n', '            raise TypeError(\n', '                f"coroutines cannot be used with {method}()")\n', '        if not callable(callback):\n', '            raise TypeError(\n', "                f'a callable object was expected by {method}(), '\n", "                f'got {callback!r}')\n", '\n', '    def _call_soon(self, callback, args, context):\n', '        handle = events.Handle(callback, args, self, context)\n', '        if handle._source_traceback:\n', '            del handle._source_traceback[-1]\n', '        self._ready.append(handle)\n', '        return handle\n', '\n', '    def _check_thread(self):\n', '        """Check that the current thread is the thread running the event loop.\n', '\n', '        Non-thread-safe methods of this class make this assumption and will\n', '        likely behave incorrectly when the assumption is violated.\n', '\n', '        Should only be called when (self._debug == True).  The caller is\n', '        responsible for checking this condition for performance reasons.\n', '        """\n', '        if self._thread_id is None:\n', '            return\n', '        thread_id = threading.get_ident()\n', '        if thread_id != self._thread_id:\n', '            raise RuntimeError(\n', '                "Non-thread-safe operation invoked on an event loop other "\n', '                "than the current one")\n', '\n', '    def call_soon_threadsafe(self, callback, *args, context=None):\n', '        """Like call_soon(), but thread-safe."""\n', '        self._check_closed()\n', '        if self._debug:\n', "            self._check_callback(callback, 'call_soon_threadsafe')\n", '        handle = self._call_soon(callback, args, context)\n', '        if handle._source_traceback:\n', '            del handle._source_traceback[-1]\n', '        self._write_to_self()\n', '        return handle\n', '\n', '    def run_in_executor(self, executor, func, *args):\n', '        self._check_closed()\n', '        if self._debug:\n', "            self._check_callback(func, 'run_in_executor')\n", '        if executor is None:\n', '            executor = self._default_executor\n', '            # Only check when the default executor is being used\n', '            self._check_default_executor()\n', '            if executor is None:\n', '                executor = concurrent.futures.ThreadPoolExecutor(\n', "                    thread_name_prefix='asyncio'\n", '                )\n', '                self._default_executor = executor\n', '        return futures.wrap_future(\n', '            executor.submit(func, *args), loop=self)\n', '\n', '    def set_default_executor(self, executor):\n', '        if not isinstance(executor, concurrent.futures.ThreadPoolExecutor):\n', '            warnings.warn(\n', "                'Using the default executor that is not an instance of '\n", "                'ThreadPoolExecutor is deprecated and will be prohibited '\n", "                'in Python 3.9',\n", '                DeprecationWarning, 2)\n', '        self._default_executor = executor\n', '\n', '    def _getaddrinfo_debug(self, host, port, family, type, proto, flags):\n', '        msg = [f"{host}:{port!r}"]\n', '        if family:\n', "            msg.append(f'family={family!r}')\n", '        if type:\n', "            msg.append(f'type={type!r}')\n", '        if proto:\n', "            msg.append(f'proto={proto!r}')\n", '        if flags:\n', "            msg.append(f'flags={flags!r}')\n", "        msg = ', '.join(msg)\n", "        logger.debug('Get address info %s', msg)\n", '\n', '        t0 = self.time()\n', '        addrinfo = socket.getaddrinfo(host, port, family, type, proto, flags)\n', '        dt = self.time() - t0\n', '\n', "        msg = f'Getting address info {msg} took {dt * 1e3:.3f}ms: {addrinfo!r}'\n", '        if dt >= self.slow_callback_duration:\n', '            logger.info(msg)\n', '        else:\n', '            logger.debug(msg)\n', '        return addrinfo\n', '\n', '    async def getaddrinfo(self, host, port, *,\n', '                          family=0, type=0, proto=0, flags=0):\n', '        if self._debug:\n', '            getaddr_func = self._getaddrinfo_debug\n', '        else:\n', '            getaddr_func = socket.getaddrinfo\n', '\n', '        return await self.run_in_executor(\n', '            None, getaddr_func, host, port, family, type, proto, flags)\n', '\n', '    async def getnameinfo(self, sockaddr, flags=0):\n', '        return await self.run_in_executor(\n', '            None, socket.getnameinfo, sockaddr, flags)\n', '\n', '    async def sock_sendfile(self, sock, file, offset=0, count=None,\n', '                            *, fallback=True):\n', '        if self._debug and sock.gettimeout() != 0:\n', '            raise ValueError("the socket must be non-blocking")\n', '        _check_ssl_socket(sock)\n', '        self._check_sendfile_params(sock, file, offset, count)\n', '        try:\n', '            return await self._sock_sendfile_native(sock, file,\n', '                                                    offset, count)\n', '        except exceptions.SendfileNotAvailableError as exc:\n', '            if not fallback:\n', '                raise\n', '        return await self._sock_sendfile_fallback(sock, file,\n', '                                                  offset, count)\n', '\n', '    async def _sock_sendfile_native(self, sock, file, offset, count):\n', '        # NB: sendfile syscall is not supported for SSL sockets and\n', '        # non-mmap files even if sendfile is supported by OS\n', '        raise exceptions.SendfileNotAvailableError(\n', '            f"syscall sendfile is not available for socket {sock!r} "\n', '            f"and file {file!r} combination")\n', '\n', '    async def _sock_sendfile_fallback(self, sock, file, offset, count):\n', '        if offset:\n', '            file.seek(offset)\n', '        blocksize = (\n', '            min(count, constants.SENDFILE_FALLBACK_READBUFFER_SIZE)\n', '            if count else constants.SENDFILE_FALLBACK_READBUFFER_SIZE\n', '        )\n', '        buf = bytearray(blocksize)\n', '        total_sent = 0\n', '        try:\n', '            while True:\n', '                if count:\n', '                    blocksize = min(count - total_sent, blocksize)\n', '                    if blocksize <= 0:\n', '                        break\n', '                view = memoryview(buf)[:blocksize]\n', '                read = await self.run_in_executor(None, file.readinto, view)\n', '                if not read:\n', '                    break  # EOF\n', '                await self.sock_sendall(sock, view[:read])\n', '                total_sent += read\n', '            return total_sent\n', '        finally:\n', "            if total_sent > 0 and hasattr(file, 'seek'):\n", '                file.seek(offset + total_sent)\n', '\n', '    def _check_sendfile_params(self, sock, file, offset, count):\n', "        if 'b' not in getattr(file, 'mode', 'b'):\n", '            raise ValueError("file should be opened in binary mode")\n', '        if not sock.type == socket.SOCK_STREAM:\n', '            raise ValueError("only SOCK_STREAM type sockets are supported")\n', '        if count is not None:\n', '            if not isinstance(count, int):\n', '                raise TypeError(\n', '                    "count must be a positive integer (got {!r})".format(count))\n', '            if count <= 0:\n', '                raise ValueError(\n', '                    "count must be a positive integer (got {!r})".format(count))\n', '        if not isinstance(offset, int):\n', '            raise TypeError(\n', '                "offset must be a non-negative integer (got {!r})".format(\n', '                    offset))\n', '        if offset < 0:\n', '            raise ValueError(\n', '                "offset must be a non-negative integer (got {!r})".format(\n', '                    offset))\n', '\n', '    async def _connect_sock(self, exceptions, addr_info, local_addr_infos=None):\n', '        """Create, bind and connect one socket."""\n', '        my_exceptions = []\n', '        exceptions.append(my_exceptions)\n', '        family, type_, proto, _, address = addr_info\n', '        sock = None\n', '        try:\n', '            sock = socket.socket(family=family, type=type_, proto=proto)\n', '            sock.setblocking(False)\n', '            if local_addr_infos is not None:\n', '                for _, _, _, _, laddr in local_addr_infos:\n', '                    try:\n', '                        sock.bind(laddr)\n', '                        break\n', '                    except OSError as exc:\n', '                        msg = (\n', "                            f'error while attempting to bind on '\n", "                            f'address {laddr!r}: '\n", "                            f'{exc.strerror.lower()}'\n", '                        )\n', '                        exc = OSError(exc.errno, msg)\n', '                        my_exceptions.append(exc)\n', '                else:  # all bind attempts failed\n', '                    raise my_exceptions.pop()\n', '            await self.sock_connect(sock, address)\n', '            return sock\n', '        except OSError as exc:\n', '            my_exceptions.append(exc)\n', '            if sock is not None:\n', '                sock.close()\n', '            raise\n', '        except:\n', '            if sock is not None:\n', '                sock.close()\n', '            raise\n', '\n', '    async def create_connection(\n', '            self, protocol_factory, host=None, port=None,\n', '            *, ssl=None, family=0,\n', '            proto=0, flags=0, sock=None,\n', '            local_addr=None, server_hostname=None,\n', '            ssl_handshake_timeout=None,\n', '            happy_eyeballs_delay=None, interleave=None):\n', '        """Connect to a TCP server.\n', '\n', '        Create a streaming transport connection to a given internet host and\n', '        port: socket family AF_INET or socket.AF_INET6 depending on host (or\n', '        family if specified), socket type SOCK_STREAM. protocol_factory must be\n', '        a callable returning a protocol instance.\n', '\n', '        This method is a coroutine which will try to establish the connection\n', '        in the background.  When successful, the coroutine returns a\n', '        (transport, protocol) pair.\n', '        """\n', '        if server_hostname is not None and not ssl:\n', "            raise ValueError('server_hostname is only meaningful with ssl')\n", '\n', '        if server_hostname is None and ssl:\n', '            # Use host as default for server_hostname.  It is an error\n', '            # if host is empty or not set, e.g. when an\n', '            # already-connected socket was passed or when only a port\n', '            # is given.  To avoid this error, you can pass\n', "            # server_hostname='' -- this will bypass the hostname\n", '            # check.  (This also means that if host is a numeric\n', '            # IP/IPv6 address, we will attempt to verify that exact\n', '            # address; this will probably fail, but it is possible to\n', '            # create a certificate for a specific IP address, so we\n', "            # don't judge it here.)\n", '            if not host:\n', "                raise ValueError('You must set server_hostname '\n", "                                 'when using ssl without a host')\n", '            server_hostname = host\n', '\n', '        if ssl_handshake_timeout is not None and not ssl:\n', '            raise ValueError(\n', "                'ssl_handshake_timeout is only meaningful with ssl')\n", '\n', '        if sock is not None:\n', '            _check_ssl_socket(sock)\n', '\n', '        if happy_eyeballs_delay is not None and interleave is None:\n', '            # If using happy eyeballs, default to interleave addresses by family\n', '            interleave = 1\n', '\n', '        if host is not None or port is not None:\n', '            if sock is not None:\n', '                raise ValueError(\n', "                    'host/port and sock can not be specified at the same time')\n", '\n', '            infos = await self._ensure_resolved(\n', '                (host, port), family=family,\n', '                type=socket.SOCK_STREAM, proto=proto, flags=flags, loop=self)\n', '            if not infos:\n', "                raise OSError('getaddrinfo() returned empty list')\n", '\n', '            if local_addr is not None:\n', '                laddr_infos = await self._ensure_resolved(\n', '                    local_addr, family=family,\n', '                    type=socket.SOCK_STREAM, proto=proto,\n', '                    flags=flags, loop=self)\n', '                if not laddr_infos:\n', "                    raise OSError('getaddrinfo() returned empty list')\n", '            else:\n', '                laddr_infos = None\n', '\n', '            if interleave:\n', '                infos = _interleave_addrinfos(infos, interleave)\n', '\n', '            exceptions = []\n', '            if happy_eyeballs_delay is None:\n', '                # not using happy eyeballs\n', '                for addrinfo in infos:\n', '                    try:\n', '                        sock = await self._connect_sock(\n', '                            exceptions, addrinfo, laddr_infos)\n', '                        break\n', '                    except OSError:\n', '                        continue\n', '            else:  # using happy eyeballs\n', '                sock, _, _ = await staggered.staggered_race(\n', '                    (functools.partial(self._connect_sock,\n', '                                       exceptions, addrinfo, laddr_infos)\n', '                     for addrinfo in infos),\n', '                    happy_eyeballs_delay, loop=self)\n', '\n', '            if sock is None:\n', '                exceptions = [exc for sub in exceptions for exc in sub]\n', '                if len(exceptions) == 1:\n', '                    raise exceptions[0]\n', '                else:\n', '                    # If they all have the same str(), raise one.\n', '                    model = str(exceptions[0])\n', '                    if all(str(exc) == model for exc in exceptions):\n', '                        raise exceptions[0]\n', '                    # Raise a combined exception so the user can see all\n', '                    # the various error messages.\n', "                    raise OSError('Multiple exceptions: {}'.format(\n", "                        ', '.join(str(exc) for exc in exceptions)))\n", '\n', '        else:\n', '            if sock is None:\n', '                raise ValueError(\n', "                    'host and port was not specified and no sock specified')\n", '            if sock.type != socket.SOCK_STREAM:\n', '                # We allow AF_INET, AF_INET6, AF_UNIX as long as they\n', '                # are SOCK_STREAM.\n', '                # We support passing AF_UNIX sockets even though we have\n', '                # a dedicated API for that: create_unix_connection.\n', '                # Disallowing AF_UNIX in this method, breaks backwards\n', '                # compatibility.\n', '                raise ValueError(\n', "                    f'A Stream Socket was expected, got {sock!r}')\n", '\n', '        transport, protocol = await self._create_connection_transport(\n', '            sock, protocol_factory, ssl, server_hostname,\n', '            ssl_handshake_timeout=ssl_handshake_timeout)\n', '        if self._debug:\n', '            # Get the socket from the transport because SSL transport closes\n', '            # the old socket and creates a new SSL socket\n', "            sock = transport.get_extra_info('socket')\n", '            logger.debug("%r connected to %s:%r: (%r, %r)",\n', '                         sock, host, port, transport, protocol)\n', '        return transport, protocol\n', '\n', '    async def _create_connection_transport(\n', '            self, sock, protocol_factory, ssl,\n', '            server_hostname, server_side=False,\n', '            ssl_handshake_timeout=None):\n', '\n', '        sock.setblocking(False)\n', '\n', '        protocol = protocol_factory()\n', '        waiter = self.create_future()\n', '        if ssl:\n', '            sslcontext = None if isinstance(ssl, bool) else ssl\n', '            transport = self._make_ssl_transport(\n', '                sock, protocol, sslcontext, waiter,\n', '                server_side=server_side, server_hostname=server_hostname,\n', '                ssl_handshake_timeout=ssl_handshake_timeout)\n', '        else:\n', '            transport = self._make_socket_transport(sock, protocol, waiter)\n', '\n', '        try:\n', '            await waiter\n', '        except:\n', '            transport.close()\n', '            raise\n', '\n', '        return transport, protocol\n', '\n', '    async def sendfile(self, transport, file, offset=0, count=None,\n', '                       *, fallback=True):\n', '        """Send a file to transport.\n', '\n', '        Return the total number of bytes which were sent.\n', '\n', '        The method uses high-performance os.sendfile if available.\n', '\n', '        file must be a regular file object opened in binary mode.\n', '\n', '        offset tells from where to start reading the file. If specified,\n', '        count is the total number of bytes to transmit as opposed to\n', '        sending the file until EOF is reached. File position is updated on\n', '        return or also in case of error in which case file.tell()\n', '        can be used to figure out the number of bytes\n', '        which were sent.\n', '\n', '        fallback set to True makes asyncio to manually read and send\n', '        the file when the platform does not support the sendfile syscall\n', '        (e.g. Windows or SSL socket on Unix).\n', '\n', '        Raise SendfileNotAvailableError if the system does not support\n', '        sendfile syscall and fallback is False.\n', '        """\n', '        if transport.is_closing():\n', '            raise RuntimeError("Transport is closing")\n', "        mode = getattr(transport, '_sendfile_compatible',\n", '                       constants._SendfileMode.UNSUPPORTED)\n', '        if mode is constants._SendfileMode.UNSUPPORTED:\n', '            raise RuntimeError(\n', '                f"sendfile is not supported for transport {transport!r}")\n', '        if mode is constants._SendfileMode.TRY_NATIVE:\n', '            try:\n', '                return await self._sendfile_native(transport, file,\n', '                                                   offset, count)\n', '            except exceptions.SendfileNotAvailableError as exc:\n', '                if not fallback:\n', '                    raise\n', '\n', '        if not fallback:\n', '            raise RuntimeError(\n', '                f"fallback is disabled and native sendfile is not "\n', '                f"supported for transport {transport!r}")\n', '\n', '        return await self._sendfile_fallback(transport, file,\n', '                                             offset, count)\n', '\n', '    async def _sendfile_native(self, transp, file, offset, count):\n', '        raise exceptions.SendfileNotAvailableError(\n', '            "sendfile syscall is not supported")\n', '\n', '    async def _sendfile_fallback(self, transp, file, offset, count):\n', '        if offset:\n', '            file.seek(offset)\n', '        blocksize = min(count, 16384) if count else 16384\n', '        buf = bytearray(blocksize)\n', '        total_sent = 0\n', '        proto = _SendfileFallbackProtocol(transp)\n', '        try:\n', '            while True:\n', '                if count:\n', '                    blocksize = min(count - total_sent, blocksize)\n', '                    if blocksize <= 0:\n', '                        return total_sent\n', '                view = memoryview(buf)[:blocksize]\n', '                read = await self.run_in_executor(None, file.readinto, view)\n', '                if not read:\n', '                    return total_sent  # EOF\n', '                await proto.drain()\n', '                transp.write(view[:read])\n', '                total_sent += read\n', '        finally:\n', "            if total_sent > 0 and hasattr(file, 'seek'):\n", '                file.seek(offset + total_sent)\n', '            await proto.restore()\n', '\n', '    async def start_tls(self, transport, protocol, sslcontext, *,\n', '                        server_side=False,\n', '                        server_hostname=None,\n', '                        ssl_handshake_timeout=None):\n', '        """Upgrade transport to TLS.\n', '\n', '        Return a new transport that *protocol* should start using\n', '        immediately.\n', '        """\n', '        if ssl is None:\n', "            raise RuntimeError('Python ssl module is not available')\n", '\n', '        if not isinstance(sslcontext, ssl.SSLContext):\n', '            raise TypeError(\n', "                f'sslcontext is expected to be an instance of ssl.SSLContext, '\n", "                f'got {sslcontext!r}')\n", '\n', "        if not getattr(transport, '_start_tls_compatible', False):\n", '            raise TypeError(\n', "                f'transport {transport!r} is not supported by start_tls()')\n", '\n', '        waiter = self.create_future()\n', '        ssl_protocol = sslproto.SSLProtocol(\n', '            self, protocol, sslcontext, waiter,\n', '            server_side, server_hostname,\n', '            ssl_handshake_timeout=ssl_handshake_timeout,\n', '            call_connection_made=False)\n', '\n', '        # Pause early so that "ssl_protocol.data_received()" doesn\'t\n', '        # have a chance to get called before "ssl_protocol.connection_made()".\n', '        transport.pause_reading()\n', '\n', '        transport.set_protocol(ssl_protocol)\n', '        conmade_cb = self.call_soon(ssl_protocol.connection_made, transport)\n', '        resume_cb = self.call_soon(transport.resume_reading)\n', '\n', '        try:\n', '            await waiter\n', '        except BaseException:\n', '            transport.close()\n', '            conmade_cb.cancel()\n', '            resume_cb.cancel()\n', '            raise\n', '\n', '        return ssl_protocol._app_transport\n', '\n', '    async def create_datagram_endpoint(self, protocol_factory,\n', '                                       local_addr=None, remote_addr=None, *,\n', '                                       family=0, proto=0, flags=0,\n', '                                       reuse_address=_unset, reuse_port=None,\n', '                                       allow_broadcast=None, sock=None):\n', '        """Create datagram connection."""\n', '        if sock is not None:\n', '            if sock.type != socket.SOCK_DGRAM:\n', '                raise ValueError(\n', "                    f'A UDP Socket was expected, got {sock!r}')\n", '            if (local_addr or remote_addr or\n', '                    family or proto or flags or\n', '                    reuse_port or allow_broadcast):\n', '                # show the problematic kwargs in exception msg\n', '                opts = dict(local_addr=local_addr, remote_addr=remote_addr,\n', '                            family=family, proto=proto, flags=flags,\n', '                            reuse_address=reuse_address, reuse_port=reuse_port,\n', '                            allow_broadcast=allow_broadcast)\n', "                problems = ', '.join(f'{k}={v}' for k, v in opts.items() if v)\n", '                raise ValueError(\n', "                    f'socket modifier keyword arguments can not be used '\n", "                    f'when sock is specified. ({problems})')\n", '            sock.setblocking(False)\n', '            r_addr = None\n', '        else:\n', '            if not (local_addr or remote_addr):\n', '                if family == 0:\n', "                    raise ValueError('unexpected address family')\n", '                addr_pairs_info = (((family, proto), (None, None)),)\n', "            elif hasattr(socket, 'AF_UNIX') and family == socket.AF_UNIX:\n", '                for addr in (local_addr, remote_addr):\n', '                    if addr is not None and not isinstance(addr, str):\n', "                        raise TypeError('string is expected')\n", '\n', "                if local_addr and local_addr[0] not in (0, '\\x00'):\n", '                    try:\n', '                        if stat.S_ISSOCK(os.stat(local_addr).st_mode):\n', '                            os.remove(local_addr)\n', '                    except FileNotFoundError:\n', '                        pass\n', '                    except OSError as err:\n', '                        # Directory may have permissions only to create socket.\n', "                        logger.error('Unable to check or remove stale UNIX '\n", "                                     'socket %r: %r',\n", '                                     local_addr, err)\n', '\n', '                addr_pairs_info = (((family, proto),\n', '                                    (local_addr, remote_addr)), )\n', '            else:\n', '                # join address by (family, protocol)\n', '                addr_infos = {}  # Using order preserving dict\n', '                for idx, addr in ((0, local_addr), (1, remote_addr)):\n', '                    if addr is not None:\n', '                        assert isinstance(addr, tuple) and len(addr) == 2, (\n', "                            '2-tuple is expected')\n", '\n', '                        infos = await self._ensure_resolved(\n', '                            addr, family=family, type=socket.SOCK_DGRAM,\n', '                            proto=proto, flags=flags, loop=self)\n', '                        if not infos:\n', "                            raise OSError('getaddrinfo() returned empty list')\n", '\n', '                        for fam, _, pro, _, address in infos:\n', '                            key = (fam, pro)\n', '                            if key not in addr_infos:\n', '                                addr_infos[key] = [None, None]\n', '                            addr_infos[key][idx] = address\n', '\n', '                # each addr has to have info for each (family, proto) pair\n', '                addr_pairs_info = [\n', '                    (key, addr_pair) for key, addr_pair in addr_infos.items()\n', '                    if not ((local_addr and addr_pair[0] is None) or\n', '                            (remote_addr and addr_pair[1] is None))]\n', '\n', '                if not addr_pairs_info:\n', "                    raise ValueError('can not get address information')\n", '\n', '            exceptions = []\n', '\n', '            # bpo-37228\n', '            if reuse_address is not _unset:\n', '                if reuse_address:\n', '                    raise ValueError("Passing `reuse_address=True` is no "\n', '                                     "longer supported, as the usage of "\n', '                                     "SO_REUSEPORT in UDP poses a significant "\n', '                                     "security concern.")\n', '                else:\n', '                    warnings.warn("The *reuse_address* parameter has been "\n', '                                  "deprecated as of 3.5.10 and is scheduled "\n', '                                  "for removal in 3.11.", DeprecationWarning,\n', '                                  stacklevel=2)\n', '\n', '            for ((family, proto),\n', '                 (local_address, remote_address)) in addr_pairs_info:\n', '                sock = None\n', '                r_addr = None\n', '                try:\n', '                    sock = socket.socket(\n', '                        family=family, type=socket.SOCK_DGRAM, proto=proto)\n', '                    if reuse_port:\n', '                        _set_reuseport(sock)\n', '                    if allow_broadcast:\n', '                        sock.setsockopt(\n', '                            socket.SOL_SOCKET, socket.SO_BROADCAST, 1)\n', '                    sock.setblocking(False)\n', '\n', '                    if local_addr:\n', '                        sock.bind(local_address)\n', '                    if remote_addr:\n', '                        if not allow_broadcast:\n', '                            await self.sock_connect(sock, remote_address)\n', '                        r_addr = remote_address\n', '                except OSError as exc:\n', '                    if sock is not None:\n', '                        sock.close()\n', '                    exceptions.append(exc)\n', '                except:\n', '                    if sock is not None:\n', '                        sock.close()\n', '                    raise\n', '                else:\n', '                    break\n', '            else:\n', '                raise exceptions[0]\n', '\n', '        protocol = protocol_factory()\n', '        waiter = self.create_future()\n', '        transport = self._make_datagram_transport(\n', '            sock, protocol, r_addr, waiter)\n', '        if self._debug:\n', '            if local_addr:\n', '                logger.info("Datagram endpoint local_addr=%r remote_addr=%r "\n', '                            "created: (%r, %r)",\n', '                            local_addr, remote_addr, transport, protocol)\n', '            else:\n', '                logger.debug("Datagram endpoint remote_addr=%r created: "\n', '                             "(%r, %r)",\n', '                             remote_addr, transport, protocol)\n', '\n', '        try:\n', '            await waiter\n', '        except:\n', '            transport.close()\n', '            raise\n', '\n', '        return transport, protocol\n', '\n', '    async def _ensure_resolved(self, address, *,\n', '                               family=0, type=socket.SOCK_STREAM,\n', '                               proto=0, flags=0, loop):\n', '        host, port = address[:2]\n', '        info = _ipaddr_info(host, port, family, type, proto, *address[2:])\n', '        if info is not None:\n', '            # "host" is already a resolved IP.\n', '            return [info]\n', '        else:\n', '            return await loop.getaddrinfo(host, port, family=family, type=type,\n', '                                          proto=proto, flags=flags)\n', '\n', '    async def _create_server_getaddrinfo(self, host, port, family, flags):\n', '        infos = await self._ensure_resolved((host, port), family=family,\n', '                                            type=socket.SOCK_STREAM,\n', '                                            flags=flags, loop=self)\n', '        if not infos:\n', "            raise OSError(f'getaddrinfo({host!r}) returned empty list')\n", '        return infos\n', '\n', '    async def create_server(\n', '            self, protocol_factory, host=None, port=None,\n', '            *,\n', '            family=socket.AF_UNSPEC,\n', '            flags=socket.AI_PASSIVE,\n', '            sock=None,\n', '            backlog=100,\n', '            ssl=None,\n', '            reuse_address=None,\n', '            reuse_port=None,\n', '            ssl_handshake_timeout=None,\n', '            start_serving=True):\n', '        """Create a TCP server.\n', '\n', '        The host parameter can be a string, in that case the TCP server is\n', '        bound to host and port.\n', '\n', '        The host parameter can also be a sequence of strings and in that case\n', '        the TCP server is bound to all hosts of the sequence. If a host\n', '        appears multiple times (possibly indirectly e.g. when hostnames\n', '        resolve to the same IP address), the server is only bound once to that\n', '        host.\n', '\n', '        Return a Server object which can be used to stop the service.\n', '\n', '        This method is a coroutine.\n', '        """\n', '        if isinstance(ssl, bool):\n', "            raise TypeError('ssl argument must be an SSLContext or None')\n", '\n', '        if ssl_handshake_timeout is not None and ssl is None:\n', '            raise ValueError(\n', "                'ssl_handshake_timeout is only meaningful with ssl')\n", '\n', '        if sock is not None:\n', '            _check_ssl_socket(sock)\n', '\n', '        if host is not None or port is not None:\n', '            if sock is not None:\n', '                raise ValueError(\n', "                    'host/port and sock can not be specified at the same time')\n", '\n', '            if reuse_address is None:\n', "                reuse_address = os.name == 'posix' and sys.platform != 'cygwin'\n", '            sockets = []\n', "            if host == '':\n", '                hosts = [None]\n', '            elif (isinstance(host, str) or\n', '                  not isinstance(host, collections.abc.Iterable)):\n', '                hosts = [host]\n', '            else:\n', '                hosts = host\n', '\n', '            fs = [self._create_server_getaddrinfo(host, port, family=family,\n', '                                                  flags=flags)\n', '                  for host in hosts]\n', '            infos = await tasks.gather(*fs)\n', '            infos = set(itertools.chain.from_iterable(infos))\n', '\n', '            completed = False\n', '            try:\n', '                for res in infos:\n', '                    af, socktype, proto, canonname, sa = res\n', '                    try:\n', '                        sock = socket.socket(af, socktype, proto)\n', '                    except socket.error:\n', "                        # Assume it's a bad family/type/protocol combination.\n", '                        if self._debug:\n', "                            logger.warning('create_server() failed to create '\n", "                                           'socket.socket(%r, %r, %r)',\n", '                                           af, socktype, proto, exc_info=True)\n', '                        continue\n', '                    sockets.append(sock)\n', '                    if reuse_address:\n', '                        sock.setsockopt(\n', '                            socket.SOL_SOCKET, socket.SO_REUSEADDR, True)\n', '                    if reuse_port:\n', '                        _set_reuseport(sock)\n', '                    # Disable IPv4/IPv6 dual stack support (enabled by\n', '                    # default on Linux) which makes a single socket\n', '                    # listen on both address families.\n', '                    if (_HAS_IPv6 and\n', '                            af == socket.AF_INET6 and\n', "                            hasattr(socket, 'IPPROTO_IPV6')):\n", '                        sock.setsockopt(socket.IPPROTO_IPV6,\n', '                                        socket.IPV6_V6ONLY,\n', '                                        True)\n', '                    try:\n', '                        sock.bind(sa)\n', '                    except OSError as err:\n', "                        raise OSError(err.errno, 'error while attempting '\n", "                                      'to bind on address %r: %s'\n", '                                      % (sa, err.strerror.lower())) from None\n', '                completed = True\n', '            finally:\n', '                if not completed:\n', '                    for sock in sockets:\n', '                        sock.close()\n', '        else:\n', '            if sock is None:\n', "                raise ValueError('Neither host/port nor sock were specified')\n", '            if sock.type != socket.SOCK_STREAM:\n', "                raise ValueError(f'A Stream Socket was expected, got {sock!r}')\n", '            sockets = [sock]\n', '\n', '        for sock in sockets:\n', '            sock.setblocking(False)\n', '\n', '        server = Server(self, sockets, protocol_factory,\n', '                        ssl, backlog, ssl_handshake_timeout)\n', '        if start_serving:\n', '            server._start_serving()\n', "            # Skip one loop iteration so that all 'loop.add_reader'\n", '            # go through.\n', '            await tasks.sleep(0)\n', '\n', '        if self._debug:\n', '            logger.info("%r is serving", server)\n', '        return server\n', '\n', '    async def connect_accepted_socket(\n', '            self, protocol_factory, sock,\n', '            *, ssl=None,\n', '            ssl_handshake_timeout=None):\n', '        if sock.type != socket.SOCK_STREAM:\n', "            raise ValueError(f'A Stream Socket was expected, got {sock!r}')\n", '\n', '        if ssl_handshake_timeout is not None and not ssl:\n', '            raise ValueError(\n', "                'ssl_handshake_timeout is only meaningful with ssl')\n", '\n', '        if sock is not None:\n', '            _check_ssl_socket(sock)\n', '\n', '        transport, protocol = await self._create_connection_transport(\n', "            sock, protocol_factory, ssl, '', server_side=True,\n", '            ssl_handshake_timeout=ssl_handshake_timeout)\n', '        if self._debug:\n', '            # Get the socket from the transport because SSL transport closes\n', '            # the old socket and creates a new SSL socket\n', "            sock = transport.get_extra_info('socket')\n", '            logger.debug("%r handled: (%r, %r)", sock, transport, protocol)\n', '        return transport, protocol\n', '\n', '    async def connect_read_pipe(self, protocol_factory, pipe):\n', '        protocol = protocol_factory()\n', '        waiter = self.create_future()\n', '        transport = self._make_read_pipe_transport(pipe, protocol, waiter)\n', '\n', '        try:\n', '            await waiter\n', '        except:\n', '            transport.close()\n', '            raise\n', '\n', '        if self._debug:\n', "            logger.debug('Read pipe %r connected: (%r, %r)',\n", '                         pipe.fileno(), transport, protocol)\n', '        return transport, protocol\n', '\n', '    async def connect_write_pipe(self, protocol_factory, pipe):\n', '        protocol = protocol_factory()\n', '        waiter = self.create_future()\n', '        transport = self._make_write_pipe_transport(pipe, protocol, waiter)\n', '\n', '        try:\n', '            await waiter\n', '        except:\n', '            transport.close()\n', '            raise\n', '\n', '        if self._debug:\n', "            logger.debug('Write pipe %r connected: (%r, %r)',\n", '                         pipe.fileno(), transport, protocol)\n', '        return transport, protocol\n', '\n', '    def _log_subprocess(self, msg, stdin, stdout, stderr):\n', '        info = [msg]\n', '        if stdin is not None:\n', "            info.append(f'stdin={_format_pipe(stdin)}')\n", '        if stdout is not None and stderr == subprocess.STDOUT:\n', "            info.append(f'stdout=stderr={_format_pipe(stdout)}')\n", '        else:\n', '            if stdout is not None:\n', "                info.append(f'stdout={_format_pipe(stdout)}')\n", '            if stderr is not None:\n', "                info.append(f'stderr={_format_pipe(stderr)}')\n", "        logger.debug(' '.join(info))\n", '\n', '    async def subprocess_shell(self, protocol_factory, cmd, *,\n', '                               stdin=subprocess.PIPE,\n', '                               stdout=subprocess.PIPE,\n', '                               stderr=subprocess.PIPE,\n', '                               universal_newlines=False,\n', '                               shell=True, bufsize=0,\n', '                               encoding=None, errors=None, text=None,\n', '                               **kwargs):\n', '        if not isinstance(cmd, (bytes, str)):\n', '            raise ValueError("cmd must be a string")\n', '        if universal_newlines:\n', '            raise ValueError("universal_newlines must be False")\n', '        if not shell:\n', '            raise ValueError("shell must be True")\n', '        if bufsize != 0:\n', '            raise ValueError("bufsize must be 0")\n', '        if text:\n', '            raise ValueError("text must be False")\n', '        if encoding is not None:\n', '            raise ValueError("encoding must be None")\n', '        if errors is not None:\n', '            raise ValueError("errors must be None")\n', '\n', '        protocol = protocol_factory()\n', '        debug_log = None\n', '        if self._debug:\n', "            # don't log parameters: they may contain sensitive information\n", '            # (password) and may be too long\n', "            debug_log = 'run shell command %r' % cmd\n", '            self._log_subprocess(debug_log, stdin, stdout, stderr)\n', '        transport = await self._make_subprocess_transport(\n', '            protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs)\n', '        if self._debug and debug_log is not None:\n', "            logger.info('%s: %r', debug_log, transport)\n", '        return transport, protocol\n', '\n', '    async def subprocess_exec(self, protocol_factory, program, *args,\n', '                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,\n', '                              stderr=subprocess.PIPE, universal_newlines=False,\n', '                              shell=False, bufsize=0,\n', '                              encoding=None, errors=None, text=None,\n', '                              **kwargs):\n', '        if universal_newlines:\n', '            raise ValueError("universal_newlines must be False")\n', '        if shell:\n', '            raise ValueError("shell must be False")\n', '        if bufsize != 0:\n', '            raise ValueError("bufsize must be 0")\n', '        if text:\n', '            raise ValueError("text must be False")\n', '        if encoding is not None:\n', '            raise ValueError("encoding must be None")\n', '        if errors is not None:\n', '            raise ValueError("errors must be None")\n', '\n', '        popen_args = (program,) + args\n', '        protocol = protocol_factory()\n', '        debug_log = None\n', '        if self._debug:\n', "            # don't log parameters: they may contain sensitive information\n", '            # (password) and may be too long\n', "            debug_log = f'execute program {program!r}'\n", '            self._log_subprocess(debug_log, stdin, stdout, stderr)\n', '        transport = await self._make_subprocess_transport(\n', '            protocol, popen_args, False, stdin, stdout, stderr,\n', '            bufsize, **kwargs)\n', '        if self._debug and debug_log is not None:\n', "            logger.info('%s: %r', debug_log, transport)\n", '        return transport, protocol\n', '\n', '    def get_exception_handler(self):\n', '        """Return an exception handler, or None if the default one is in use.\n', '        """\n', '        return self._exception_handler\n', '\n', '    def set_exception_handler(self, handler):\n', '        """Set handler as the new event loop exception handler.\n', '\n', '        If handler is None, the default exception handler will\n', '        be set.\n', '\n', '        If handler is a callable object, it should have a\n', "        signature matching '(loop, context)', where 'loop'\n", "        will be a reference to the active event loop, 'context'\n", '        will be a dict object (see `call_exception_handler()`\n', '        documentation for details about context).\n', '        """\n', '        if handler is not None and not callable(handler):\n', "            raise TypeError(f'A callable object or None is expected, '\n", "                            f'got {handler!r}')\n", '        self._exception_handler = handler\n', '\n', '    def default_exception_handler(self, context):\n', '        """Default exception handler.\n', '\n', '        This is called when an exception occurs and no exception\n', '        handler is set, and can be called by a custom exception\n', '        handler that wants to defer to the default behavior.\n', '\n', '        This default handler logs the error message and other\n', '        context-dependent information.  In debug mode, a truncated\n', '        stack trace is also appended showing where the given object\n', '        (e.g. a handle or future or task) was created, if any.\n', '\n', '        The context parameter has the same meaning as in\n', '        `call_exception_handler()`.\n', '        """\n', "        message = context.get('message')\n", '        if not message:\n', "            message = 'Unhandled exception in event loop'\n", '\n', "        exception = context.get('exception')\n", '        if exception is not None:\n', '            exc_info = (type(exception), exception, exception.__traceback__)\n', '        else:\n', '            exc_info = False\n', '\n', "        if ('source_traceback' not in context and\n", '                self._current_handle is not None and\n', '                self._current_handle._source_traceback):\n', "            context['handle_traceback'] = \\\n", '                self._current_handle._source_traceback\n', '\n', '        log_lines = [message]\n', '        for key in sorted(context):\n', "            if key in {'message', 'exception'}:\n", '                continue\n', '            value = context[key]\n', "            if key == 'source_traceback':\n", "                tb = ''.join(traceback.format_list(value))\n", "                value = 'Object created at (most recent call last):\\n'\n", '                value += tb.rstrip()\n', "            elif key == 'handle_traceback':\n", "                tb = ''.join(traceback.format_list(value))\n", "                value = 'Handle created at (most recent call last):\\n'\n", '                value += tb.rstrip()\n', '            else:\n', '                value = repr(value)\n', "            log_lines.append(f'{key}: {value}')\n", '\n', "        logger.error('\\n'.join(log_lines), exc_info=exc_info)\n", '\n', '    def call_exception_handler(self, context):\n', '        """Call the current event loop\'s exception handler.\n', '\n', '        The context argument is a dict containing the following keys:\n', '\n', "        - 'message': Error message;\n", "        - 'exception' (optional): Exception object;\n", "        - 'future' (optional): Future instance;\n", "        - 'task' (optional): Task instance;\n", "        - 'handle' (optional): Handle instance;\n", "        - 'protocol' (optional): Protocol instance;\n", "        - 'transport' (optional): Transport instance;\n", "        - 'socket' (optional): Socket instance;\n", "        - 'asyncgen' (optional): Asynchronous generator that caused\n", '                                 the exception.\n', '\n', '        New keys maybe introduced in the future.\n', '\n', '        Note: do not overload this method in an event loop subclass.\n', '        For custom exception handling, use the\n', '        `set_exception_handler()` method.\n', '        """\n', '        if self._exception_handler is None:\n', '            try:\n', '                self.default_exception_handler(context)\n', '            except (SystemExit, KeyboardInterrupt):\n', '                raise\n', '            except BaseException:\n', '                # Second protection layer for unexpected errors\n', '                # in the default implementation, as well as for subclassed\n', '                # event loops with overloaded "default_exception_handler".\n', "                logger.error('Exception in default exception handler',\n", '                             exc_info=True)\n', '        else:\n', '            try:\n', '                self._exception_handler(self, context)\n', '            except (SystemExit, KeyboardInterrupt):\n', '                raise\n', '            except BaseException as exc:\n', '                # Exception in the user set custom exception handler.\n', '                try:\n', "                    # Let's try default handler.\n", '                    self.default_exception_handler({\n', "                        'message': 'Unhandled error in exception handler',\n", "                        'exception': exc,\n", "                        'context': context,\n", '                    })\n', '                except (SystemExit, KeyboardInterrupt):\n', '                    raise\n', '                except BaseException:\n', "                    # Guard 'default_exception_handler' in case it is\n", '                    # overloaded.\n', "                    logger.error('Exception in default exception handler '\n", "                                 'while handling an unexpected error '\n", "                                 'in custom exception handler',\n", '                                 exc_info=True)\n', '\n', '    def _add_callback(self, handle):\n', '        """Add a Handle to _scheduled (TimerHandle) or _ready."""\n', "        assert isinstance(handle, events.Handle), 'A Handle is required here'\n", '        if handle._cancelled:\n', '            return\n', '        assert not isinstance(handle, events.TimerHandle)\n', '        self._ready.append(handle)\n', '\n', '    def _add_callback_signalsafe(self, handle):\n', '        """Like _add_callback() but called from a signal handler."""\n', '        self._add_callback(handle)\n', '        self._write_to_self()\n', '\n', '    def _timer_handle_cancelled(self, handle):\n', '        """Notification that a TimerHandle has been cancelled."""\n', '        if handle._scheduled:\n', '            self._timer_cancelled_count += 1\n', '\n', '    def _run_once(self):\n', '        """Run one full iteration of the event loop.\n', '\n', '        This calls all currently ready callbacks, polls for I/O,\n', '        schedules the resulting callbacks, and finally schedules\n', "        'call_later' callbacks.\n", '        """\n', '\n', '        sched_count = len(self._scheduled)\n', '        if (sched_count > _MIN_SCHEDULED_TIMER_HANDLES and\n', '            self._timer_cancelled_count / sched_count >\n', '                _MIN_CANCELLED_TIMER_HANDLES_FRACTION):\n', '            # Remove delayed calls that were cancelled if their number\n', '            # is too high\n', '            new_scheduled = []\n', '            for handle in self._scheduled:\n', '                if handle._cancelled:\n', '                    handle._scheduled = False\n', '                else:\n', '                    new_scheduled.append(handle)\n', '\n', '            heapq.heapify(new_scheduled)\n', '            self._scheduled = new_scheduled\n', '            self._timer_cancelled_count = 0\n', '        else:\n', '            # Remove delayed calls that were cancelled from head of queue.\n', '            while self._scheduled and self._scheduled[0]._cancelled:\n', '                self._timer_cancelled_count -= 1\n', '                handle = heapq.heappop(self._scheduled)\n', '                handle._scheduled = False\n', '\n', '        timeout = None\n', '        if self._ready or self._stopping:\n', '            timeout = 0\n', '        elif self._scheduled:\n', '            # Compute the desired timeout.\n', '            when = self._scheduled[0]._when\n', '            timeout = min(max(0, when - self.time()), MAXIMUM_SELECT_TIMEOUT)\n', '\n', '        event_list = self._selector.select(timeout)\n', '        self._process_events(event_list)\n', '\n', "        # Handle 'later' callbacks that are ready.\n", '        end_time = self.time() + self._clock_resolution\n', '        while self._scheduled:\n', '            handle = self._scheduled[0]\n', '            if handle._when >= end_time:\n', '                break\n', '            handle = heapq.heappop(self._scheduled)\n', '            handle._scheduled = False\n', '            self._ready.append(handle)\n', '\n', '        # This is the only place where callbacks are actually *called*.\n', '        # All other places just add them to ready.\n', '        # Note: We run all currently scheduled callbacks, but not any\n', '        # callbacks scheduled by callbacks run this time around --\n', '        # they will be run the next time (after another I/O poll).\n', '        # Use an idiom that is thread-safe without using locks.\n', '        ntodo = len(self._ready)\n', '        for i in range(ntodo):\n', '            handle = self._ready.popleft()\n', '            if handle._cancelled:\n', '                continue\n', '            if self._debug:\n', '                try:\n', '                    self._current_handle = handle\n', '                    t0 = self.time()\n', '                    handle._run()\n', '                    dt = self.time() - t0\n', '                    if dt >= self.slow_callback_duration:\n', "                        logger.warning('Executing %s took %.3f seconds',\n", '                                       _format_handle(handle), dt)\n', '                finally:\n', '                    self._current_handle = None\n', '            else:\n', '                handle._run()\n', '        handle = None  # Needed to break cycles when an exception occurs.\n', '\n', '    def _set_coroutine_origin_tracking(self, enabled):\n', '        if bool(enabled) == bool(self._coroutine_origin_tracking_enabled):\n', '            return\n', '\n', '        if enabled:\n', '            self._coroutine_origin_tracking_saved_depth = (\n', '                sys.get_coroutine_origin_tracking_depth())\n', '            sys.set_coroutine_origin_tracking_depth(\n', '                constants.DEBUG_STACK_DEPTH)\n', '        else:\n', '            sys.set_coroutine_origin_tracking_depth(\n', '                self._coroutine_origin_tracking_saved_depth)\n', '\n', '        self._coroutine_origin_tracking_enabled = enabled\n', '\n', '    def get_debug(self):\n', '        return self._debug\n', '\n', '    def set_debug(self, enabled):\n', '        self._debug = enabled\n', '\n', '        if self.is_running():\n', '            self.call_soon_threadsafe(self._set_coroutine_origin_tracking, enabled)\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/base_events.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/unix_events.py': (51674, 1.0, ['"""Selector event loop for Unix with signal handling."""\n', '\n', 'import errno\n', 'import io\n', 'import itertools\n', 'import os\n', 'import selectors\n', 'import signal\n', 'import socket\n', 'import stat\n', 'import subprocess\n', 'import sys\n', 'import threading\n', 'import warnings\n', '\n', 'from . import base_events\n', 'from . import base_subprocess\n', 'from . import constants\n', 'from . import coroutines\n', 'from . import events\n', 'from . import exceptions\n', 'from . import futures\n', 'from . import selector_events\n', 'from . import tasks\n', 'from . import transports\n', 'from .log import logger\n', '\n', '\n', '__all__ = (\n', "    'SelectorEventLoop',\n", "    'AbstractChildWatcher', 'SafeChildWatcher',\n", "    'FastChildWatcher', 'PidfdChildWatcher',\n", "    'MultiLoopChildWatcher', 'ThreadedChildWatcher',\n", "    'DefaultEventLoopPolicy',\n", ')\n', '\n', '\n', "if sys.platform == 'win32':  # pragma: no cover\n", "    raise ImportError('Signals are not really supported on Windows')\n", '\n', '\n', 'def _sighandler_noop(signum, frame):\n', '    """Dummy signal handler."""\n', '    pass\n', '\n', '\n', 'def waitstatus_to_exitcode(status):\n', '    try:\n', '        return os.waitstatus_to_exitcode(status)\n', '    except ValueError:\n', "        # The child exited, but we don't understand its status.\n", "        # This shouldn't happen, but if it does, let's just\n", '        # return that status; perhaps that helps debug it.\n', '        return status\n', '\n', '\n', 'class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):\n', '    """Unix event loop.\n', '\n', '    Adds signal handling and UNIX Domain Socket support to SelectorEventLoop.\n', '    """\n', '\n', '    def __init__(self, selector=None):\n', '        super().__init__(selector)\n', '        self._signal_handlers = {}\n', '\n', '    def close(self):\n', '        super().close()\n', '        if not sys.is_finalizing():\n', '            for sig in list(self._signal_handlers):\n', '                self.remove_signal_handler(sig)\n', '        else:\n', '            if self._signal_handlers:\n', '                warnings.warn(f"Closing the loop {self!r} "\n', '                              f"on interpreter shutdown "\n', '                              f"stage, skipping signal handlers removal",\n', '                              ResourceWarning,\n', '                              source=self)\n', '                self._signal_handlers.clear()\n', '\n', '    def _process_self_data(self, data):\n', '        for signum in data:\n', '            if not signum:\n', '                # ignore null bytes written by _write_to_self()\n', '                continue\n', '            self._handle_signal(signum)\n', '\n', '    def add_signal_handler(self, sig, callback, *args):\n', '        """Add a handler for a signal.  UNIX only.\n', '\n', '        Raise ValueError if the signal number is invalid or uncatchable.\n', '        Raise RuntimeError if there is a problem setting up the handler.\n', '        """\n', '        if (coroutines.iscoroutine(callback) or\n', '                coroutines.iscoroutinefunction(callback)):\n', '            raise TypeError("coroutines cannot be used "\n', '                            "with add_signal_handler()")\n', '        self._check_signal(sig)\n', '        self._check_closed()\n', '        try:\n', '            # set_wakeup_fd() raises ValueError if this is not the\n', '            # main thread.  By calling it early we ensure that an\n', '            # event loop running in another thread cannot add a signal\n', '            # handler.\n', '            signal.set_wakeup_fd(self._csock.fileno())\n', '        except (ValueError, OSError) as exc:\n', '            raise RuntimeError(str(exc))\n', '\n', '        handle = events.Handle(callback, args, self, None)\n', '        self._signal_handlers[sig] = handle\n', '\n', '        try:\n', '            # Register a dummy signal handler to ask Python to write the signal\n', '            # number in the wakeup file descriptor. _process_self_data() will\n', '            # read signal numbers from this file descriptor to handle signals.\n', '            signal.signal(sig, _sighandler_noop)\n', '\n', '            # Set SA_RESTART to limit EINTR occurrences.\n', '            signal.siginterrupt(sig, False)\n', '        except OSError as exc:\n', '            del self._signal_handlers[sig]\n', '            if not self._signal_handlers:\n', '                try:\n', '                    signal.set_wakeup_fd(-1)\n', '                except (ValueError, OSError) as nexc:\n', "                    logger.info('set_wakeup_fd(-1) failed: %s', nexc)\n", '\n', '            if exc.errno == errno.EINVAL:\n', "                raise RuntimeError(f'sig {sig} cannot be caught')\n", '            else:\n', '                raise\n', '\n', '    def _handle_signal(self, sig):\n', '        """Internal helper that is the actual signal handler."""\n', '        handle = self._signal_handlers.get(sig)\n', '        if handle is None:\n', "            return  # Assume it's some race condition.\n", '        if handle._cancelled:\n', '            self.remove_signal_handler(sig)  # Remove it properly.\n', '        else:\n', '            self._add_callback_signalsafe(handle)\n', '\n', '    def remove_signal_handler(self, sig):\n', '        """Remove a handler for a signal.  UNIX only.\n', '\n', '        Return True if a signal handler was removed, False if not.\n', '        """\n', '        self._check_signal(sig)\n', '        try:\n', '            del self._signal_handlers[sig]\n', '        except KeyError:\n', '            return False\n', '\n', '        if sig == signal.SIGINT:\n', '            handler = signal.default_int_handler\n', '        else:\n', '            handler = signal.SIG_DFL\n', '\n', '        try:\n', '            signal.signal(sig, handler)\n', '        except OSError as exc:\n', '            if exc.errno == errno.EINVAL:\n', "                raise RuntimeError(f'sig {sig} cannot be caught')\n", '            else:\n', '                raise\n', '\n', '        if not self._signal_handlers:\n', '            try:\n', '                signal.set_wakeup_fd(-1)\n', '            except (ValueError, OSError) as exc:\n', "                logger.info('set_wakeup_fd(-1) failed: %s', exc)\n", '\n', '        return True\n', '\n', '    def _check_signal(self, sig):\n', '        """Internal helper to validate a signal.\n', '\n', '        Raise ValueError if the signal number is invalid or uncatchable.\n', '        Raise RuntimeError if there is a problem setting up the handler.\n', '        """\n', '        if not isinstance(sig, int):\n', "            raise TypeError(f'sig must be an int, not {sig!r}')\n", '\n', '        if sig not in signal.valid_signals():\n', "            raise ValueError(f'invalid signal number {sig}')\n", '\n', '    def _make_read_pipe_transport(self, pipe, protocol, waiter=None,\n', '                                  extra=None):\n', '        return _UnixReadPipeTransport(self, pipe, protocol, waiter, extra)\n', '\n', '    def _make_write_pipe_transport(self, pipe, protocol, waiter=None,\n', '                                   extra=None):\n', '        return _UnixWritePipeTransport(self, pipe, protocol, waiter, extra)\n', '\n', '    async def _make_subprocess_transport(self, protocol, args, shell,\n', '                                         stdin, stdout, stderr, bufsize,\n', '                                         extra=None, **kwargs):\n', '        with events.get_child_watcher() as watcher:\n', '            if not watcher.is_active():\n', '                # Check early.\n', '                # Raising exception before process creation\n', '                # prevents subprocess execution if the watcher\n', '                # is not ready to handle it.\n', '                raise RuntimeError("asyncio.get_child_watcher() is not activated, "\n', '                                   "subprocess support is not installed.")\n', '            waiter = self.create_future()\n', '            transp = _UnixSubprocessTransport(self, protocol, args, shell,\n', '                                              stdin, stdout, stderr, bufsize,\n', '                                              waiter=waiter, extra=extra,\n', '                                              **kwargs)\n', '\n', '            watcher.add_child_handler(transp.get_pid(),\n', '                                      self._child_watcher_callback, transp)\n', '            try:\n', '                await waiter\n', '            except (SystemExit, KeyboardInterrupt):\n', '                raise\n', '            except BaseException:\n', '                transp.close()\n', '                await transp._wait()\n', '                raise\n', '\n', '        return transp\n', '\n', '    def _child_watcher_callback(self, pid, returncode, transp):\n', '        # Skip one iteration for callbacks to be executed\n', '        self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode)\n', '\n', '    async def create_unix_connection(\n', '            self, protocol_factory, path=None, *,\n', '            ssl=None, sock=None,\n', '            server_hostname=None,\n', '            ssl_handshake_timeout=None):\n', '        assert server_hostname is None or isinstance(server_hostname, str)\n', '        if ssl:\n', '            if server_hostname is None:\n', '                raise ValueError(\n', "                    'you have to pass server_hostname when using ssl')\n", '        else:\n', '            if server_hostname is not None:\n', "                raise ValueError('server_hostname is only meaningful with ssl')\n", '            if ssl_handshake_timeout is not None:\n', '                raise ValueError(\n', "                    'ssl_handshake_timeout is only meaningful with ssl')\n", '\n', '        if path is not None:\n', '            if sock is not None:\n', '                raise ValueError(\n', "                    'path and sock can not be specified at the same time')\n", '\n', '            path = os.fspath(path)\n', '            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)\n', '            try:\n', '                sock.setblocking(False)\n', '                await self.sock_connect(sock, path)\n', '            except:\n', '                sock.close()\n', '                raise\n', '\n', '        else:\n', '            if sock is None:\n', "                raise ValueError('no path and sock were specified')\n", '            if (sock.family != socket.AF_UNIX or\n', '                    sock.type != socket.SOCK_STREAM):\n', '                raise ValueError(\n', "                    f'A UNIX Domain Stream Socket was expected, got {sock!r}')\n", '            sock.setblocking(False)\n', '\n', '        transport, protocol = await self._create_connection_transport(\n', '            sock, protocol_factory, ssl, server_hostname,\n', '            ssl_handshake_timeout=ssl_handshake_timeout)\n', '        return transport, protocol\n', '\n', '    async def create_unix_server(\n', '            self, protocol_factory, path=None, *,\n', '            sock=None, backlog=100, ssl=None,\n', '            ssl_handshake_timeout=None,\n', '            start_serving=True):\n', '        if isinstance(ssl, bool):\n', "            raise TypeError('ssl argument must be an SSLContext or None')\n", '\n', '        if ssl_handshake_timeout is not None and not ssl:\n', '            raise ValueError(\n', "                'ssl_handshake_timeout is only meaningful with ssl')\n", '\n', '        if path is not None:\n', '            if sock is not None:\n', '                raise ValueError(\n', "                    'path and sock can not be specified at the same time')\n", '\n', '            path = os.fspath(path)\n', '            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n', '\n', '            # Check for abstract socket. `str` and `bytes` paths are supported.\n', "            if path[0] not in (0, '\\x00'):\n", '                try:\n', '                    if stat.S_ISSOCK(os.stat(path).st_mode):\n', '                        os.remove(path)\n', '                except FileNotFoundError:\n', '                    pass\n', '                except OSError as err:\n', '                    # Directory may have permissions only to create socket.\n', "                    logger.error('Unable to check or remove stale UNIX socket '\n", "                                 '%r: %r', path, err)\n", '\n', '            try:\n', '                sock.bind(path)\n', '            except OSError as exc:\n', '                sock.close()\n', '                if exc.errno == errno.EADDRINUSE:\n', "                    # Let's improve the error message by adding\n", '                    # with what exact address it occurs.\n', "                    msg = f'Address {path!r} is already in use'\n", '                    raise OSError(errno.EADDRINUSE, msg) from None\n', '                else:\n', '                    raise\n', '            except:\n', '                sock.close()\n', '                raise\n', '        else:\n', '            if sock is None:\n', '                raise ValueError(\n', "                    'path was not specified, and no sock specified')\n", '\n', '            if (sock.family != socket.AF_UNIX or\n', '                    sock.type != socket.SOCK_STREAM):\n', '                raise ValueError(\n', "                    f'A UNIX Domain Stream Socket was expected, got {sock!r}')\n", '\n', '        sock.setblocking(False)\n', '        server = base_events.Server(self, [sock], protocol_factory,\n', '                                    ssl, backlog, ssl_handshake_timeout)\n', '        if start_serving:\n', '            server._start_serving()\n', "            # Skip one loop iteration so that all 'loop.add_reader'\n", '            # go through.\n', '            await tasks.sleep(0)\n', '\n', '        return server\n', '\n', '    async def _sock_sendfile_native(self, sock, file, offset, count):\n', '        try:\n', '            os.sendfile\n', '        except AttributeError:\n', '            raise exceptions.SendfileNotAvailableError(\n', '                "os.sendfile() is not available")\n', '        try:\n', '            fileno = file.fileno()\n', '        except (AttributeError, io.UnsupportedOperation) as err:\n', '            raise exceptions.SendfileNotAvailableError("not a regular file")\n', '        try:\n', '            fsize = os.fstat(fileno).st_size\n', '        except OSError:\n', '            raise exceptions.SendfileNotAvailableError("not a regular file")\n', '        blocksize = count if count else fsize\n', '        if not blocksize:\n', '            return 0  # empty file\n', '\n', '        fut = self.create_future()\n', '        self._sock_sendfile_native_impl(fut, None, sock, fileno,\n', '                                        offset, count, blocksize, 0)\n', '        return await fut\n', '\n', '    def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,\n', '                                   offset, count, blocksize, total_sent):\n', '        fd = sock.fileno()\n', '        if registered_fd is not None:\n', '            # Remove the callback early.  It should be rare that the\n', '            # selector says the fd is ready but the call still returns\n', '            # EAGAIN, and I am willing to take a hit in that case in\n', '            # order to simplify the common case.\n', '            self.remove_writer(registered_fd)\n', '        if fut.cancelled():\n', '            self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '            return\n', '        if count:\n', '            blocksize = count - total_sent\n', '            if blocksize <= 0:\n', '                self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '                fut.set_result(total_sent)\n', '                return\n', '\n', '        try:\n', '            sent = os.sendfile(fd, fileno, offset, blocksize)\n', '        except (BlockingIOError, InterruptedError):\n', '            if registered_fd is None:\n', '                self._sock_add_cancellation_callback(fut, sock)\n', '            self.add_writer(fd, self._sock_sendfile_native_impl, fut,\n', '                            fd, sock, fileno,\n', '                            offset, count, blocksize, total_sent)\n', '        except OSError as exc:\n', '            if (registered_fd is not None and\n', '                    exc.errno == errno.ENOTCONN and\n', '                    type(exc) is not ConnectionError):\n', "                # If we have an ENOTCONN and this isn't a first call to\n", '                # sendfile(), i.e. the connection was closed in the middle\n', '                # of the operation, normalize the error to ConnectionError\n', '                # to make it consistent across all Posix systems.\n', '                new_exc = ConnectionError(\n', '                    "socket is not connected", errno.ENOTCONN)\n', '                new_exc.__cause__ = exc\n', '                exc = new_exc\n', '            if total_sent == 0:\n', '                # We can get here for different reasons, the main\n', "                # one being 'file' is not a regular mmap(2)-like\n", "                # file, in which case we'll fall back on using\n", '                # plain send().\n', '                err = exceptions.SendfileNotAvailableError(\n', '                    "os.sendfile call failed")\n', '                self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '                fut.set_exception(err)\n', '            else:\n', '                self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '                fut.set_exception(exc)\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException as exc:\n', '            self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '            fut.set_exception(exc)\n', '        else:\n', '            if sent == 0:\n', '                # EOF\n', '                self._sock_sendfile_update_filepos(fileno, offset, total_sent)\n', '                fut.set_result(total_sent)\n', '            else:\n', '                offset += sent\n', '                total_sent += sent\n', '                if registered_fd is None:\n', '                    self._sock_add_cancellation_callback(fut, sock)\n', '                self.add_writer(fd, self._sock_sendfile_native_impl, fut,\n', '                                fd, sock, fileno,\n', '                                offset, count, blocksize, total_sent)\n', '\n', '    def _sock_sendfile_update_filepos(self, fileno, offset, total_sent):\n', '        if total_sent > 0:\n', '            os.lseek(fileno, offset, os.SEEK_SET)\n', '\n', '    def _sock_add_cancellation_callback(self, fut, sock):\n', '        def cb(fut):\n', '            if fut.cancelled():\n', '                fd = sock.fileno()\n', '                if fd != -1:\n', '                    self.remove_writer(fd)\n', '        fut.add_done_callback(cb)\n', '\n', '\n', 'class _UnixReadPipeTransport(transports.ReadTransport):\n', '\n', '    max_size = 256 * 1024  # max bytes we read in one event loop iteration\n', '\n', '    def __init__(self, loop, pipe, protocol, waiter=None, extra=None):\n', '        super().__init__(extra)\n', "        self._extra['pipe'] = pipe\n", '        self._loop = loop\n', '        self._pipe = pipe\n', '        self._fileno = pipe.fileno()\n', '        self._protocol = protocol\n', '        self._closing = False\n', '        self._paused = False\n', '\n', '        mode = os.fstat(self._fileno).st_mode\n', '        if not (stat.S_ISFIFO(mode) or\n', '                stat.S_ISSOCK(mode) or\n', '                stat.S_ISCHR(mode)):\n', '            self._pipe = None\n', '            self._fileno = None\n', '            self._protocol = None\n', '            raise ValueError("Pipe transport is for pipes/sockets only.")\n', '\n', '        os.set_blocking(self._fileno, False)\n', '\n', '        self._loop.call_soon(self._protocol.connection_made, self)\n', '        # only start reading when connection_made() has been called\n', '        self._loop.call_soon(self._loop._add_reader,\n', '                             self._fileno, self._read_ready)\n', '        if waiter is not None:\n', '            # only wake up the waiter when connection_made() has been called\n', '            self._loop.call_soon(futures._set_result_unless_cancelled,\n', '                                 waiter, None)\n', '\n', '    def __repr__(self):\n', '        info = [self.__class__.__name__]\n', '        if self._pipe is None:\n', "            info.append('closed')\n", '        elif self._closing:\n', "            info.append('closing')\n", "        info.append(f'fd={self._fileno}')\n", "        selector = getattr(self._loop, '_selector', None)\n", '        if self._pipe is not None and selector is not None:\n', '            polling = selector_events._test_selector_event(\n', '                selector, self._fileno, selectors.EVENT_READ)\n', '            if polling:\n', "                info.append('polling')\n", '            else:\n', "                info.append('idle')\n", '        elif self._pipe is not None:\n', "            info.append('open')\n", '        else:\n', "            info.append('closed')\n", "        return '<{}>'.format(' '.join(info))\n", '\n', '    def _read_ready(self):\n', '        try:\n', '            data = os.read(self._fileno, self.max_size)\n', '        except (BlockingIOError, InterruptedError):\n', '            pass\n', '        except OSError as exc:\n', "            self._fatal_error(exc, 'Fatal read error on pipe transport')\n", '        else:\n', '            if data:\n', '                self._protocol.data_received(data)\n', '            else:\n', '                if self._loop.get_debug():\n', '                    logger.info("%r was closed by peer", self)\n', '                self._closing = True\n', '                self._loop._remove_reader(self._fileno)\n', '                self._loop.call_soon(self._protocol.eof_received)\n', '                self._loop.call_soon(self._call_connection_lost, None)\n', '\n', '    def pause_reading(self):\n', '        if self._closing or self._paused:\n', '            return\n', '        self._paused = True\n', '        self._loop._remove_reader(self._fileno)\n', '        if self._loop.get_debug():\n', '            logger.debug("%r pauses reading", self)\n', '\n', '    def resume_reading(self):\n', '        if self._closing or not self._paused:\n', '            return\n', '        self._paused = False\n', '        self._loop._add_reader(self._fileno, self._read_ready)\n', '        if self._loop.get_debug():\n', '            logger.debug("%r resumes reading", self)\n', '\n', '    def set_protocol(self, protocol):\n', '        self._protocol = protocol\n', '\n', '    def get_protocol(self):\n', '        return self._protocol\n', '\n', '    def is_closing(self):\n', '        return self._closing\n', '\n', '    def close(self):\n', '        if not self._closing:\n', '            self._close(None)\n', '\n', '    def __del__(self, _warn=warnings.warn):\n', '        if self._pipe is not None:\n', '            _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)\n', '            self._pipe.close()\n', '\n', "    def _fatal_error(self, exc, message='Fatal error on pipe transport'):\n", '        # should be called by exception handler only\n', '        if (isinstance(exc, OSError) and exc.errno == errno.EIO):\n', '            if self._loop.get_debug():\n', '                logger.debug("%r: %s", self, message, exc_info=True)\n', '        else:\n', '            self._loop.call_exception_handler({\n', "                'message': message,\n", "                'exception': exc,\n", "                'transport': self,\n", "                'protocol': self._protocol,\n", '            })\n', '        self._close(exc)\n', '\n', '    def _close(self, exc):\n', '        self._closing = True\n', '        self._loop._remove_reader(self._fileno)\n', '        self._loop.call_soon(self._call_connection_lost, exc)\n', '\n', '    def _call_connection_lost(self, exc):\n', '        try:\n', '            self._protocol.connection_lost(exc)\n', '        finally:\n', '            self._pipe.close()\n', '            self._pipe = None\n', '            self._protocol = None\n', '            self._loop = None\n', '\n', '\n', 'class _UnixWritePipeTransport(transports._FlowControlMixin,\n', '                              transports.WriteTransport):\n', '\n', '    def __init__(self, loop, pipe, protocol, waiter=None, extra=None):\n', '        super().__init__(extra, loop)\n', "        self._extra['pipe'] = pipe\n", '        self._pipe = pipe\n', '        self._fileno = pipe.fileno()\n', '        self._protocol = protocol\n', '        self._buffer = bytearray()\n', '        self._conn_lost = 0\n', '        self._closing = False  # Set when close() or write_eof() called.\n', '\n', '        mode = os.fstat(self._fileno).st_mode\n', '        is_char = stat.S_ISCHR(mode)\n', '        is_fifo = stat.S_ISFIFO(mode)\n', '        is_socket = stat.S_ISSOCK(mode)\n', '        if not (is_char or is_fifo or is_socket):\n', '            self._pipe = None\n', '            self._fileno = None\n', '            self._protocol = None\n', '            raise ValueError("Pipe transport is only for "\n', '                             "pipes, sockets and character devices")\n', '\n', '        os.set_blocking(self._fileno, False)\n', '        self._loop.call_soon(self._protocol.connection_made, self)\n', '\n', '        # On AIX, the reader trick (to be notified when the read end of the\n', '        # socket is closed) only works for sockets. On other platforms it\n', '        # works for pipes and sockets. (Exception: OS X 10.4?  Issue #19294.)\n', '        if is_socket or (is_fifo and not sys.platform.startswith("aix")):\n', '            # only start reading when connection_made() has been called\n', '            self._loop.call_soon(self._loop._add_reader,\n', '                                 self._fileno, self._read_ready)\n', '\n', '        if waiter is not None:\n', '            # only wake up the waiter when connection_made() has been called\n', '            self._loop.call_soon(futures._set_result_unless_cancelled,\n', '                                 waiter, None)\n', '\n', '    def __repr__(self):\n', '        info = [self.__class__.__name__]\n', '        if self._pipe is None:\n', "            info.append('closed')\n", '        elif self._closing:\n', "            info.append('closing')\n", "        info.append(f'fd={self._fileno}')\n", "        selector = getattr(self._loop, '_selector', None)\n", '        if self._pipe is not None and selector is not None:\n', '            polling = selector_events._test_selector_event(\n', '                selector, self._fileno, selectors.EVENT_WRITE)\n', '            if polling:\n', "                info.append('polling')\n", '            else:\n', "                info.append('idle')\n", '\n', '            bufsize = self.get_write_buffer_size()\n', "            info.append(f'bufsize={bufsize}')\n", '        elif self._pipe is not None:\n', "            info.append('open')\n", '        else:\n', "            info.append('closed')\n", "        return '<{}>'.format(' '.join(info))\n", '\n', '    def get_write_buffer_size(self):\n', '        return len(self._buffer)\n', '\n', '    def _read_ready(self):\n', '        # Pipe was closed by peer.\n', '        if self._loop.get_debug():\n', '            logger.info("%r was closed by peer", self)\n', '        if self._buffer:\n', '            self._close(BrokenPipeError())\n', '        else:\n', '            self._close()\n', '\n', '    def write(self, data):\n', '        assert isinstance(data, (bytes, bytearray, memoryview)), repr(data)\n', '        if isinstance(data, bytearray):\n', '            data = memoryview(data)\n', '        if not data:\n', '            return\n', '\n', '        if self._conn_lost or self._closing:\n', '            if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:\n', "                logger.warning('pipe closed by peer or '\n", "                               'os.write(pipe, data) raised exception.')\n", '            self._conn_lost += 1\n', '            return\n', '\n', '        if not self._buffer:\n', '            # Attempt to send it right away first.\n', '            try:\n', '                n = os.write(self._fileno, data)\n', '            except (BlockingIOError, InterruptedError):\n', '                n = 0\n', '            except (SystemExit, KeyboardInterrupt):\n', '                raise\n', '            except BaseException as exc:\n', '                self._conn_lost += 1\n', "                self._fatal_error(exc, 'Fatal write error on pipe transport')\n", '                return\n', '            if n == len(data):\n', '                return\n', '            elif n > 0:\n', '                data = memoryview(data)[n:]\n', '            self._loop._add_writer(self._fileno, self._write_ready)\n', '\n', '        self._buffer += data\n', '        self._maybe_pause_protocol()\n', '\n', '    def _write_ready(self):\n', "        assert self._buffer, 'Data should not be empty'\n", '\n', '        try:\n', '            n = os.write(self._fileno, self._buffer)\n', '        except (BlockingIOError, InterruptedError):\n', '            pass\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException as exc:\n', '            self._buffer.clear()\n', '            self._conn_lost += 1\n', "            # Remove writer here, _fatal_error() doesn't it\n", '            # because _buffer is empty.\n', '            self._loop._remove_writer(self._fileno)\n', "            self._fatal_error(exc, 'Fatal write error on pipe transport')\n", '        else:\n', '            if n == len(self._buffer):\n', '                self._buffer.clear()\n', '                self._loop._remove_writer(self._fileno)\n', '                self._maybe_resume_protocol()  # May append to buffer.\n', '                if self._closing:\n', '                    self._loop._remove_reader(self._fileno)\n', '                    self._call_connection_lost(None)\n', '                return\n', '            elif n > 0:\n', '                del self._buffer[:n]\n', '\n', '    def can_write_eof(self):\n', '        return True\n', '\n', '    def write_eof(self):\n', '        if self._closing:\n', '            return\n', '        assert self._pipe\n', '        self._closing = True\n', '        if not self._buffer:\n', '            self._loop._remove_reader(self._fileno)\n', '            self._loop.call_soon(self._call_connection_lost, None)\n', '\n', '    def set_protocol(self, protocol):\n', '        self._protocol = protocol\n', '\n', '    def get_protocol(self):\n', '        return self._protocol\n', '\n', '    def is_closing(self):\n', '        return self._closing\n', '\n', '    def close(self):\n', '        if self._pipe is not None and not self._closing:\n', '            # write_eof is all what we needed to close the write pipe\n', '            self.write_eof()\n', '\n', '    def __del__(self, _warn=warnings.warn):\n', '        if self._pipe is not None:\n', '            _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)\n', '            self._pipe.close()\n', '\n', '    def abort(self):\n', '        self._close(None)\n', '\n', "    def _fatal_error(self, exc, message='Fatal error on pipe transport'):\n", '        # should be called by exception handler only\n', '        if isinstance(exc, OSError):\n', '            if self._loop.get_debug():\n', '                logger.debug("%r: %s", self, message, exc_info=True)\n', '        else:\n', '            self._loop.call_exception_handler({\n', "                'message': message,\n", "                'exception': exc,\n", "                'transport': self,\n", "                'protocol': self._protocol,\n", '            })\n', '        self._close(exc)\n', '\n', '    def _close(self, exc=None):\n', '        self._closing = True\n', '        if self._buffer:\n', '            self._loop._remove_writer(self._fileno)\n', '        self._buffer.clear()\n', '        self._loop._remove_reader(self._fileno)\n', '        self._loop.call_soon(self._call_connection_lost, exc)\n', '\n', '    def _call_connection_lost(self, exc):\n', '        try:\n', '            self._protocol.connection_lost(exc)\n', '        finally:\n', '            self._pipe.close()\n', '            self._pipe = None\n', '            self._protocol = None\n', '            self._loop = None\n', '\n', '\n', 'class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport):\n', '\n', '    def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):\n', '        stdin_w = None\n', '        if stdin == subprocess.PIPE:\n', '            # Use a socket pair for stdin, since not all platforms\n', '            # support selecting read events on the write end of a\n', '            # socket (which we use in order to detect closing of the\n', '            # other end).  Notably this is needed on AIX, and works\n', '            # just fine on other platforms.\n', '            stdin, stdin_w = socket.socketpair()\n', '        try:\n', '            self._proc = subprocess.Popen(\n', '                args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr,\n', '                universal_newlines=False, bufsize=bufsize, **kwargs)\n', '            if stdin_w is not None:\n', '                stdin.close()\n', "                self._proc.stdin = open(stdin_w.detach(), 'wb', buffering=bufsize)\n", '                stdin_w = None\n', '        finally:\n', '            if stdin_w is not None:\n', '                stdin.close()\n', '                stdin_w.close()\n', '\n', '\n', 'class AbstractChildWatcher:\n', '    """Abstract base class for monitoring child processes.\n', '\n', '    Objects derived from this class monitor a collection of subprocesses and\n', '    report their termination or interruption by a signal.\n', '\n', '    New callbacks are registered with .add_child_handler(). Starting a new\n', "    process must be done within a 'with' block to allow the watcher to suspend\n", '    its activity until the new process if fully registered (this is needed to\n', '    prevent a race condition in some implementations).\n', '\n', '    Example:\n', '        with watcher:\n', '            proc = subprocess.Popen("sleep 1")\n', '            watcher.add_child_handler(proc.pid, callback)\n', '\n', '    Notes:\n', '        Implementations of this class must be thread-safe.\n', '\n', '        Since child watcher objects may catch the SIGCHLD signal and call\n', '        waitpid(-1), there should be only one active object per process.\n', '    """\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        """Register a new child handler.\n', '\n', '        Arrange for callback(pid, returncode, *args) to be called when\n', "        process 'pid' terminates. Specifying another callback for the same\n", '        process replaces the previous handler.\n', '\n', '        Note: callback() must be thread-safe.\n', '        """\n', '        raise NotImplementedError()\n', '\n', '    def remove_child_handler(self, pid):\n', '        """Removes the handler for process \'pid\'.\n', '\n', '        The function returns True if the handler was successfully removed,\n', '        False if there was nothing to remove."""\n', '\n', '        raise NotImplementedError()\n', '\n', '    def attach_loop(self, loop):\n', '        """Attach the watcher to an event loop.\n', '\n', '        If the watcher was previously attached to an event loop, then it is\n', '        first detached before attaching to the new loop.\n', '\n', '        Note: loop may be None.\n', '        """\n', '        raise NotImplementedError()\n', '\n', '    def close(self):\n', '        """Close the watcher.\n', '\n', '        This must be called to make sure that any underlying resource is freed.\n', '        """\n', '        raise NotImplementedError()\n', '\n', '    def is_active(self):\n', '        """Return ``True`` if the watcher is active and is used by the event loop.\n', '\n', '        Return True if the watcher is installed and ready to handle process exit\n', '        notifications.\n', '\n', '        """\n', '        raise NotImplementedError()\n', '\n', '    def __enter__(self):\n', '        """Enter the watcher\'s context and allow starting new processes\n', '\n', '        This function must return self"""\n', '        raise NotImplementedError()\n', '\n', '    def __exit__(self, a, b, c):\n', '        """Exit the watcher\'s context"""\n', '        raise NotImplementedError()\n', '\n', '\n', 'class PidfdChildWatcher(AbstractChildWatcher):\n', '    """Child watcher implementation using Linux\'s pid file descriptors.\n', '\n', '    This child watcher polls process file descriptors (pidfds) to await child\n', '    process termination. In some respects, PidfdChildWatcher is a "Goldilocks"\n', "    child watcher implementation. It doesn't require signals or threads, doesn't\n", '    interfere with any processes launched outside the event loop, and scales\n', '    linearly with the number of subprocesses launched by the event loop. The\n', '    main disadvantage is that pidfds are specific to Linux, and only work on\n', '    recent (5.3+) kernels.\n', '    """\n', '\n', '    def __init__(self):\n', '        self._loop = None\n', '        self._callbacks = {}\n', '\n', '    def __enter__(self):\n', '        return self\n', '\n', '    def __exit__(self, exc_type, exc_value, exc_traceback):\n', '        pass\n', '\n', '    def is_active(self):\n', '        return self._loop is not None and self._loop.is_running()\n', '\n', '    def close(self):\n', '        self.attach_loop(None)\n', '\n', '    def attach_loop(self, loop):\n', '        if self._loop is not None and loop is None and self._callbacks:\n', '            warnings.warn(\n', "                'A loop is being detached '\n", "                'from a child watcher with pending handlers',\n", '                RuntimeWarning)\n', '        for pidfd, _, _ in self._callbacks.values():\n', '            self._loop._remove_reader(pidfd)\n', '            os.close(pidfd)\n', '        self._callbacks.clear()\n', '        self._loop = loop\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        existing = self._callbacks.get(pid)\n', '        if existing is not None:\n', '            self._callbacks[pid] = existing[0], callback, args\n', '        else:\n', '            pidfd = os.pidfd_open(pid)\n', '            self._loop._add_reader(pidfd, self._do_wait, pid)\n', '            self._callbacks[pid] = pidfd, callback, args\n', '\n', '    def _do_wait(self, pid):\n', '        pidfd, callback, args = self._callbacks.pop(pid)\n', '        self._loop._remove_reader(pidfd)\n', '        try:\n', '            _, status = os.waitpid(pid, 0)\n', '        except ChildProcessError:\n', '            # The child process is already reaped\n', '            # (may happen if waitpid() is called elsewhere).\n', '            returncode = 255\n', '            logger.warning(\n', '                "child process pid %d exit status already read: "\n', '                " will report returncode 255",\n', '                pid)\n', '        else:\n', '            returncode = waitstatus_to_exitcode(status)\n', '\n', '        os.close(pidfd)\n', '        callback(pid, returncode, *args)\n', '\n', '    def remove_child_handler(self, pid):\n', '        try:\n', '            pidfd, _, _ = self._callbacks.pop(pid)\n', '        except KeyError:\n', '            return False\n', '        self._loop._remove_reader(pidfd)\n', '        os.close(pidfd)\n', '        return True\n', '\n', '\n', 'class BaseChildWatcher(AbstractChildWatcher):\n', '\n', '    def __init__(self):\n', '        self._loop = None\n', '        self._callbacks = {}\n', '\n', '    def close(self):\n', '        self.attach_loop(None)\n', '\n', '    def is_active(self):\n', '        return self._loop is not None and self._loop.is_running()\n', '\n', '    def _do_waitpid(self, expected_pid):\n', '        raise NotImplementedError()\n', '\n', '    def _do_waitpid_all(self):\n', '        raise NotImplementedError()\n', '\n', '    def attach_loop(self, loop):\n', '        assert loop is None or isinstance(loop, events.AbstractEventLoop)\n', '\n', '        if self._loop is not None and loop is None and self._callbacks:\n', '            warnings.warn(\n', "                'A loop is being detached '\n", "                'from a child watcher with pending handlers',\n", '                RuntimeWarning)\n', '\n', '        if self._loop is not None:\n', '            self._loop.remove_signal_handler(signal.SIGCHLD)\n', '\n', '        self._loop = loop\n', '        if loop is not None:\n', '            loop.add_signal_handler(signal.SIGCHLD, self._sig_chld)\n', '\n', '            # Prevent a race condition in case a child terminated\n', '            # during the switch.\n', '            self._do_waitpid_all()\n', '\n', '    def _sig_chld(self):\n', '        try:\n', '            self._do_waitpid_all()\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException as exc:\n', '            # self._loop should always be available here\n', "            # as '_sig_chld' is added as a signal handler\n", "            # in 'attach_loop'\n", '            self._loop.call_exception_handler({\n', "                'message': 'Unknown exception in SIGCHLD handler',\n", "                'exception': exc,\n", '            })\n', '\n', '\n', 'class SafeChildWatcher(BaseChildWatcher):\n', '    """\'Safe\' child watcher implementation.\n', '\n', '    This implementation avoids disrupting other code spawning processes by\n', '    polling explicitly each process in the SIGCHLD handler instead of calling\n', '    os.waitpid(-1).\n', '\n', '    This is a safe solution but it has a significant overhead when handling a\n', '    big number of children (O(n) each time SIGCHLD is raised)\n', '    """\n', '\n', '    def close(self):\n', '        self._callbacks.clear()\n', '        super().close()\n', '\n', '    def __enter__(self):\n', '        return self\n', '\n', '    def __exit__(self, a, b, c):\n', '        pass\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        self._callbacks[pid] = (callback, args)\n', '\n', '        # Prevent a race condition in case the child is already terminated.\n', '        self._do_waitpid(pid)\n', '\n', '    def remove_child_handler(self, pid):\n', '        try:\n', '            del self._callbacks[pid]\n', '            return True\n', '        except KeyError:\n', '            return False\n', '\n', '    def _do_waitpid_all(self):\n', '\n', '        for pid in list(self._callbacks):\n', '            self._do_waitpid(pid)\n', '\n', '    def _do_waitpid(self, expected_pid):\n', '        assert expected_pid > 0\n', '\n', '        try:\n', '            pid, status = os.waitpid(expected_pid, os.WNOHANG)\n', '        except ChildProcessError:\n', '            # The child process is already reaped\n', '            # (may happen if waitpid() is called elsewhere).\n', '            pid = expected_pid\n', '            returncode = 255\n', '            logger.warning(\n', '                "Unknown child process pid %d, will report returncode 255",\n', '                pid)\n', '        else:\n', '            if pid == 0:\n', '                # The child process is still alive.\n', '                return\n', '\n', '            returncode = waitstatus_to_exitcode(status)\n', '            if self._loop.get_debug():\n', "                logger.debug('process %s exited with returncode %s',\n", '                             expected_pid, returncode)\n', '\n', '        try:\n', '            callback, args = self._callbacks.pop(pid)\n', '        except KeyError:  # pragma: no cover\n', '            # May happen if .remove_child_handler() is called\n', '            # after os.waitpid() returns.\n', '            if self._loop.get_debug():\n', '                logger.warning("Child watcher got an unexpected pid: %r",\n', '                               pid, exc_info=True)\n', '        else:\n', '            callback(pid, returncode, *args)\n', '\n', '\n', 'class FastChildWatcher(BaseChildWatcher):\n', '    """\'Fast\' child watcher implementation.\n', '\n', '    This implementation reaps every terminated processes by calling\n', '    os.waitpid(-1) directly, possibly breaking other code spawning processes\n', '    and waiting for their termination.\n', '\n', '    There is no noticeable overhead when handling a big number of children\n', '    (O(1) each time a child terminates).\n', '    """\n', '    def __init__(self):\n', '        super().__init__()\n', '        self._lock = threading.Lock()\n', '        self._zombies = {}\n', '        self._forks = 0\n', '\n', '    def close(self):\n', '        self._callbacks.clear()\n', '        self._zombies.clear()\n', '        super().close()\n', '\n', '    def __enter__(self):\n', '        with self._lock:\n', '            self._forks += 1\n', '\n', '            return self\n', '\n', '    def __exit__(self, a, b, c):\n', '        with self._lock:\n', '            self._forks -= 1\n', '\n', '            if self._forks or not self._zombies:\n', '                return\n', '\n', '            collateral_victims = str(self._zombies)\n', '            self._zombies.clear()\n', '\n', '        logger.warning(\n', '            "Caught subprocesses termination from unknown pids: %s",\n', '            collateral_victims)\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        assert self._forks, "Must use the context manager"\n', '\n', '        with self._lock:\n', '            try:\n', '                returncode = self._zombies.pop(pid)\n', '            except KeyError:\n', '                # The child is running.\n', '                self._callbacks[pid] = callback, args\n', '                return\n', '\n', '        # The child is dead already. We can fire the callback.\n', '        callback(pid, returncode, *args)\n', '\n', '    def remove_child_handler(self, pid):\n', '        try:\n', '            del self._callbacks[pid]\n', '            return True\n', '        except KeyError:\n', '            return False\n', '\n', '    def _do_waitpid_all(self):\n', '        # Because of signal coalescing, we must keep calling waitpid() as\n', "        # long as we're able to reap a child.\n", '        while True:\n', '            try:\n', '                pid, status = os.waitpid(-1, os.WNOHANG)\n', '            except ChildProcessError:\n', '                # No more child processes exist.\n', '                return\n', '            else:\n', '                if pid == 0:\n', '                    # A child process is still alive.\n', '                    return\n', '\n', '                returncode = waitstatus_to_exitcode(status)\n', '\n', '            with self._lock:\n', '                try:\n', '                    callback, args = self._callbacks.pop(pid)\n', '                except KeyError:\n', '                    # unknown child\n', '                    if self._forks:\n', '                        # It may not be registered yet.\n', '                        self._zombies[pid] = returncode\n', '                        if self._loop.get_debug():\n', "                            logger.debug('unknown process %s exited '\n", "                                         'with returncode %s',\n", '                                         pid, returncode)\n', '                        continue\n', '                    callback = None\n', '                else:\n', '                    if self._loop.get_debug():\n', "                        logger.debug('process %s exited with returncode %s',\n", '                                     pid, returncode)\n', '\n', '            if callback is None:\n', '                logger.warning(\n', '                    "Caught subprocess termination from unknown pid: "\n', '                    "%d -> %d", pid, returncode)\n', '            else:\n', '                callback(pid, returncode, *args)\n', '\n', '\n', 'class MultiLoopChildWatcher(AbstractChildWatcher):\n', '    """A watcher that doesn\'t require running loop in the main thread.\n', '\n', '    This implementation registers a SIGCHLD signal handler on\n', '    instantiation (which may conflict with other code that\n', '    install own handler for this signal).\n', '\n', '    The solution is safe but it has a significant overhead when\n', '    handling a big number of processes (*O(n)* each time a\n', '    SIGCHLD is received).\n', '    """\n', '\n', '    # Implementation note:\n', '    # The class keeps compatibility with AbstractChildWatcher ABC\n', '    # To achieve this it has empty attach_loop() method\n', "    # and doesn't accept explicit loop argument\n", '    # for add_child_handler()/remove_child_handler()\n', '    # but retrieves the current loop by get_running_loop()\n', '\n', '    def __init__(self):\n', '        self._callbacks = {}\n', '        self._saved_sighandler = None\n', '\n', '    def is_active(self):\n', '        return self._saved_sighandler is not None\n', '\n', '    def close(self):\n', '        self._callbacks.clear()\n', '        if self._saved_sighandler is None:\n', '            return\n', '\n', '        handler = signal.getsignal(signal.SIGCHLD)\n', '        if handler != self._sig_chld:\n', '            logger.warning("SIGCHLD handler was changed by outside code")\n', '        else:\n', '            signal.signal(signal.SIGCHLD, self._saved_sighandler)\n', '        self._saved_sighandler = None\n', '\n', '    def __enter__(self):\n', '        return self\n', '\n', '    def __exit__(self, exc_type, exc_val, exc_tb):\n', '        pass\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        loop = events.get_running_loop()\n', '        self._callbacks[pid] = (loop, callback, args)\n', '\n', '        # Prevent a race condition in case the child is already terminated.\n', '        self._do_waitpid(pid)\n', '\n', '    def remove_child_handler(self, pid):\n', '        try:\n', '            del self._callbacks[pid]\n', '            return True\n', '        except KeyError:\n', '            return False\n', '\n', '    def attach_loop(self, loop):\n', "        # Don't save the loop but initialize itself if called first time\n", '        # The reason to do it here is that attach_loop() is called from\n', '        # unix policy only for the main thread.\n', '        # Main thread is required for subscription on SIGCHLD signal\n', '        if self._saved_sighandler is not None:\n', '            return\n', '\n', '        self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld)\n', '        if self._saved_sighandler is None:\n', '            logger.warning("Previous SIGCHLD handler was set by non-Python code, "\n', '                           "restore to default handler on watcher close.")\n', '            self._saved_sighandler = signal.SIG_DFL\n', '\n', '        # Set SA_RESTART to limit EINTR occurrences.\n', '        signal.siginterrupt(signal.SIGCHLD, False)\n', '\n', '    def _do_waitpid_all(self):\n', '        for pid in list(self._callbacks):\n', '            self._do_waitpid(pid)\n', '\n', '    def _do_waitpid(self, expected_pid):\n', '        assert expected_pid > 0\n', '\n', '        try:\n', '            pid, status = os.waitpid(expected_pid, os.WNOHANG)\n', '        except ChildProcessError:\n', '            # The child process is already reaped\n', '            # (may happen if waitpid() is called elsewhere).\n', '            pid = expected_pid\n', '            returncode = 255\n', '            logger.warning(\n', '                "Unknown child process pid %d, will report returncode 255",\n', '                pid)\n', '            debug_log = False\n', '        else:\n', '            if pid == 0:\n', '                # The child process is still alive.\n', '                return\n', '\n', '            returncode = waitstatus_to_exitcode(status)\n', '            debug_log = True\n', '        try:\n', '            loop, callback, args = self._callbacks.pop(pid)\n', '        except KeyError:  # pragma: no cover\n', '            # May happen if .remove_child_handler() is called\n', '            # after os.waitpid() returns.\n', '            logger.warning("Child watcher got an unexpected pid: %r",\n', '                           pid, exc_info=True)\n', '        else:\n', '            if loop.is_closed():\n', '                logger.warning("Loop %r that handles pid %r is closed", loop, pid)\n', '            else:\n', '                if debug_log and loop.get_debug():\n', "                    logger.debug('process %s exited with returncode %s',\n", '                                 expected_pid, returncode)\n', '                loop.call_soon_threadsafe(callback, pid, returncode, *args)\n', '\n', '    def _sig_chld(self, signum, frame):\n', '        try:\n', '            self._do_waitpid_all()\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException:\n', "            logger.warning('Unknown exception in SIGCHLD handler', exc_info=True)\n", '\n', '\n', 'class ThreadedChildWatcher(AbstractChildWatcher):\n', '    """Threaded child watcher implementation.\n', '\n', '    The watcher uses a thread per process\n', '    for waiting for the process finish.\n', '\n', "    It doesn't require subscription on POSIX signal\n", '    but a thread creation is not free.\n', '\n', "    The watcher has O(1) complexity, its performance doesn't depend\n", '    on amount of spawn processes.\n', '    """\n', '\n', '    def __init__(self):\n', '        self._pid_counter = itertools.count(0)\n', '        self._threads = {}\n', '\n', '    def is_active(self):\n', '        return True\n', '\n', '    def close(self):\n', '        self._join_threads()\n', '\n', '    def _join_threads(self):\n', '        """Internal: Join all non-daemon threads"""\n', '        threads = [thread for thread in list(self._threads.values())\n', '                   if thread.is_alive() and not thread.daemon]\n', '        for thread in threads:\n', '            thread.join()\n', '\n', '    def __enter__(self):\n', '        return self\n', '\n', '    def __exit__(self, exc_type, exc_val, exc_tb):\n', '        pass\n', '\n', '    def __del__(self, _warn=warnings.warn):\n', '        threads = [thread for thread in list(self._threads.values())\n', '                   if thread.is_alive()]\n', '        if threads:\n', '            _warn(f"{self.__class__} has registered but not finished child processes",\n', '                  ResourceWarning,\n', '                  source=self)\n', '\n', '    def add_child_handler(self, pid, callback, *args):\n', '        loop = events.get_running_loop()\n', '        thread = threading.Thread(target=self._do_waitpid,\n', '                                  name=f"waitpid-{next(self._pid_counter)}",\n', '                                  args=(loop, pid, callback, args),\n', '                                  daemon=True)\n', '        self._threads[pid] = thread\n', '        thread.start()\n', '\n', '    def remove_child_handler(self, pid):\n', '        # asyncio never calls remove_child_handler() !!!\n', '        # The method is no-op but is implemented because\n', '        # abstract base classes require it.\n', '        return True\n', '\n', '    def attach_loop(self, loop):\n', '        pass\n', '\n', '    def _do_waitpid(self, loop, expected_pid, callback, args):\n', '        assert expected_pid > 0\n', '\n', '        try:\n', '            pid, status = os.waitpid(expected_pid, 0)\n', '        except ChildProcessError:\n', '            # The child process is already reaped\n', '            # (may happen if waitpid() is called elsewhere).\n', '            pid = expected_pid\n', '            returncode = 255\n', '            logger.warning(\n', '                "Unknown child process pid %d, will report returncode 255",\n', '                pid)\n', '        else:\n', '            returncode = waitstatus_to_exitcode(status)\n', '            if loop.get_debug():\n', "                logger.debug('process %s exited with returncode %s',\n", '                             expected_pid, returncode)\n', '\n', '        if loop.is_closed():\n', '            logger.warning("Loop %r that handles pid %r is closed", loop, pid)\n', '        else:\n', '            loop.call_soon_threadsafe(callback, pid, returncode, *args)\n', '\n', '        self._threads.pop(expected_pid)\n', '\n', '\n', 'class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):\n', '    """UNIX event loop policy with a watcher for child processes."""\n', '    _loop_factory = _UnixSelectorEventLoop\n', '\n', '    def __init__(self):\n', '        super().__init__()\n', '        self._watcher = None\n', '\n', '    def _init_watcher(self):\n', '        with events._lock:\n', '            if self._watcher is None:  # pragma: no branch\n', '                self._watcher = ThreadedChildWatcher()\n', '                if threading.current_thread() is threading.main_thread():\n', '                    self._watcher.attach_loop(self._local._loop)\n', '\n', '    def set_event_loop(self, loop):\n', '        """Set the event loop.\n', '\n', '        As a side effect, if a child watcher was set before, then calling\n', '        .set_event_loop() from the main thread will call .attach_loop(loop) on\n', '        the child watcher.\n', '        """\n', '\n', '        super().set_event_loop(loop)\n', '\n', '        if (self._watcher is not None and\n', '                threading.current_thread() is threading.main_thread()):\n', '            self._watcher.attach_loop(loop)\n', '\n', '    def get_child_watcher(self):\n', '        """Get the watcher for child processes.\n', '\n', '        If not yet set, a ThreadedChildWatcher object is automatically created.\n', '        """\n', '        if self._watcher is None:\n', '            self._init_watcher()\n', '\n', '        return self._watcher\n', '\n', '    def set_child_watcher(self, watcher):\n', '        """Set the watcher for child processes."""\n', '\n', '        assert watcher is None or isinstance(watcher, AbstractChildWatcher)\n', '\n', '        if self._watcher is not None:\n', '            self._watcher.close()\n', '\n', '        self._watcher = watcher\n', '\n', '\n', 'SelectorEventLoop = _UnixSelectorEventLoop\n', 'DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/unix_events.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/base_subprocess.py': (8843, 1.0, ['import collections\n', 'import subprocess\n', 'import warnings\n', '\n', 'from . import protocols\n', 'from . import transports\n', 'from .log import logger\n', '\n', '\n', 'class BaseSubprocessTransport(transports.SubprocessTransport):\n', '\n', '    def __init__(self, loop, protocol, args, shell,\n', '                 stdin, stdout, stderr, bufsize,\n', '                 waiter=None, extra=None, **kwargs):\n', '        super().__init__(extra)\n', '        self._closed = False\n', '        self._protocol = protocol\n', '        self._loop = loop\n', '        self._proc = None\n', '        self._pid = None\n', '        self._returncode = None\n', '        self._exit_waiters = []\n', '        self._pending_calls = collections.deque()\n', '        self._pipes = {}\n', '        self._finished = False\n', '\n', '        if stdin == subprocess.PIPE:\n', '            self._pipes[0] = None\n', '        if stdout == subprocess.PIPE:\n', '            self._pipes[1] = None\n', '        if stderr == subprocess.PIPE:\n', '            self._pipes[2] = None\n', '\n', '        # Create the child process: set the _proc attribute\n', '        try:\n', '            self._start(args=args, shell=shell, stdin=stdin, stdout=stdout,\n', '                        stderr=stderr, bufsize=bufsize, **kwargs)\n', '        except:\n', '            self.close()\n', '            raise\n', '\n', '        self._pid = self._proc.pid\n', "        self._extra['subprocess'] = self._proc\n", '\n', '        if self._loop.get_debug():\n', '            if isinstance(args, (bytes, str)):\n', '                program = args\n', '            else:\n', '                program = args[0]\n', "            logger.debug('process %r created: pid %s',\n", '                         program, self._pid)\n', '\n', '        self._loop.create_task(self._connect_pipes(waiter))\n', '\n', '    def __repr__(self):\n', '        info = [self.__class__.__name__]\n', '        if self._closed:\n', "            info.append('closed')\n", '        if self._pid is not None:\n', "            info.append(f'pid={self._pid}')\n", '        if self._returncode is not None:\n', "            info.append(f'returncode={self._returncode}')\n", '        elif self._pid is not None:\n', "            info.append('running')\n", '        else:\n', "            info.append('not started')\n", '\n', '        stdin = self._pipes.get(0)\n', '        if stdin is not None:\n', "            info.append(f'stdin={stdin.pipe}')\n", '\n', '        stdout = self._pipes.get(1)\n', '        stderr = self._pipes.get(2)\n', '        if stdout is not None and stderr is stdout:\n', "            info.append(f'stdout=stderr={stdout.pipe}')\n", '        else:\n', '            if stdout is not None:\n', "                info.append(f'stdout={stdout.pipe}')\n", '            if stderr is not None:\n', "                info.append(f'stderr={stderr.pipe}')\n", '\n', "        return '<{}>'.format(' '.join(info))\n", '\n', '    def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):\n', '        raise NotImplementedError\n', '\n', '    def set_protocol(self, protocol):\n', '        self._protocol = protocol\n', '\n', '    def get_protocol(self):\n', '        return self._protocol\n', '\n', '    def is_closing(self):\n', '        return self._closed\n', '\n', '    def close(self):\n', '        if self._closed:\n', '            return\n', '        self._closed = True\n', '\n', '        for proto in self._pipes.values():\n', '            if proto is None:\n', '                continue\n', '            proto.pipe.close()\n', '\n', '        if (self._proc is not None and\n', '                # has the child process finished?\n', '                self._returncode is None and\n', '                # the child process has finished, but the\n', "                # transport hasn't been notified yet?\n", '                self._proc.poll() is None):\n', '\n', '            if self._loop.get_debug():\n', "                logger.warning('Close running child process: kill %r', self)\n", '\n', '            try:\n', '                self._proc.kill()\n', '            except ProcessLookupError:\n', '                pass\n', '\n', "            # Don't clear the _proc reference yet: _post_init() may still run\n", '\n', '    def __del__(self, _warn=warnings.warn):\n', '        if not self._closed:\n', '            _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)\n', '            self.close()\n', '\n', '    def get_pid(self):\n', '        return self._pid\n', '\n', '    def get_returncode(self):\n', '        return self._returncode\n', '\n', '    def get_pipe_transport(self, fd):\n', '        if fd in self._pipes:\n', '            return self._pipes[fd].pipe\n', '        else:\n', '            return None\n', '\n', '    def _check_proc(self):\n', '        if self._proc is None:\n', '            raise ProcessLookupError()\n', '\n', '    def send_signal(self, signal):\n', '        self._check_proc()\n', '        self._proc.send_signal(signal)\n', '\n', '    def terminate(self):\n', '        self._check_proc()\n', '        self._proc.terminate()\n', '\n', '    def kill(self):\n', '        self._check_proc()\n', '        self._proc.kill()\n', '\n', '    async def _connect_pipes(self, waiter):\n', '        try:\n', '            proc = self._proc\n', '            loop = self._loop\n', '\n', '            if proc.stdin is not None:\n', '                _, pipe = await loop.connect_write_pipe(\n', '                    lambda: WriteSubprocessPipeProto(self, 0),\n', '                    proc.stdin)\n', '                self._pipes[0] = pipe\n', '\n', '            if proc.stdout is not None:\n', '                _, pipe = await loop.connect_read_pipe(\n', '                    lambda: ReadSubprocessPipeProto(self, 1),\n', '                    proc.stdout)\n', '                self._pipes[1] = pipe\n', '\n', '            if proc.stderr is not None:\n', '                _, pipe = await loop.connect_read_pipe(\n', '                    lambda: ReadSubprocessPipeProto(self, 2),\n', '                    proc.stderr)\n', '                self._pipes[2] = pipe\n', '\n', '            assert self._pending_calls is not None\n', '\n', '            loop.call_soon(self._protocol.connection_made, self)\n', '            for callback, data in self._pending_calls:\n', '                loop.call_soon(callback, *data)\n', '            self._pending_calls = None\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException as exc:\n', '            if waiter is not None and not waiter.cancelled():\n', '                waiter.set_exception(exc)\n', '        else:\n', '            if waiter is not None and not waiter.cancelled():\n', '                waiter.set_result(None)\n', '\n', '    def _call(self, cb, *data):\n', '        if self._pending_calls is not None:\n', '            self._pending_calls.append((cb, data))\n', '        else:\n', '            self._loop.call_soon(cb, *data)\n', '\n', '    def _pipe_connection_lost(self, fd, exc):\n', '        self._call(self._protocol.pipe_connection_lost, fd, exc)\n', '        self._try_finish()\n', '\n', '    def _pipe_data_received(self, fd, data):\n', '        self._call(self._protocol.pipe_data_received, fd, data)\n', '\n', '    def _process_exited(self, returncode):\n', '        assert returncode is not None, returncode\n', '        assert self._returncode is None, self._returncode\n', '        if self._loop.get_debug():\n', "            logger.info('%r exited with return code %r', self, returncode)\n", '        self._returncode = returncode\n', '        if self._proc.returncode is None:\n', '            # asyncio uses a child watcher: copy the status into the Popen\n', '            # object. On Python 3.6, it is required to avoid a ResourceWarning.\n', '            self._proc.returncode = returncode\n', '        self._call(self._protocol.process_exited)\n', '        self._try_finish()\n', '\n', '        # wake up futures waiting for wait()\n', '        for waiter in self._exit_waiters:\n', '            if not waiter.cancelled():\n', '                waiter.set_result(returncode)\n', '        self._exit_waiters = None\n', '\n', '    async def _wait(self):\n', '        """Wait until the process exit and return the process return code.\n', '\n', '        This method is a coroutine."""\n', '        if self._returncode is not None:\n', '            return self._returncode\n', '\n', '        waiter = self._loop.create_future()\n', '        self._exit_waiters.append(waiter)\n', '        return await waiter\n', '\n', '    def _try_finish(self):\n', '        assert not self._finished\n', '        if self._returncode is None:\n', '            return\n', '        if all(p is not None and p.disconnected\n', '               for p in self._pipes.values()):\n', '            self._finished = True\n', '            self._call(self._call_connection_lost, None)\n', '\n', '    def _call_connection_lost(self, exc):\n', '        try:\n', '            self._protocol.connection_lost(exc)\n', '        finally:\n', '            self._loop = None\n', '            self._proc = None\n', '            self._protocol = None\n', '\n', '\n', 'class WriteSubprocessPipeProto(protocols.BaseProtocol):\n', '\n', '    def __init__(self, proc, fd):\n', '        self.proc = proc\n', '        self.fd = fd\n', '        self.pipe = None\n', '        self.disconnected = False\n', '\n', '    def connection_made(self, transport):\n', '        self.pipe = transport\n', '\n', '    def __repr__(self):\n', "        return f'<{self.__class__.__name__} fd={self.fd} pipe={self.pipe!r}>'\n", '\n', '    def connection_lost(self, exc):\n', '        self.disconnected = True\n', '        self.proc._pipe_connection_lost(self.fd, exc)\n', '        self.proc = None\n', '\n', '    def pause_writing(self):\n', '        self.proc._protocol.pause_writing()\n', '\n', '    def resume_writing(self):\n', '        self.proc._protocol.resume_writing()\n', '\n', '\n', 'class ReadSubprocessPipeProto(WriteSubprocessPipeProto,\n', '                              protocols.Protocol):\n', '\n', '    def data_received(self, data):\n', '        self.proc._pipe_data_received(self.fd, data)\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/base_subprocess.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/subprocess.py': (84053, 1.0, ['# subprocess - Subprocesses with accessible I/O streams\n', '#\n', '# For more information about this module, see PEP 324.\n', '#\n', '# Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se>\n', '#\n', '# Licensed to PSF under a Contributor Agreement.\n', '\n', 'r"""Subprocesses with accessible I/O streams\n', '\n', 'This module allows you to spawn processes, connect to their\n', 'input/output/error pipes, and obtain their return codes.\n', '\n', 'For a complete description of this module see the Python documentation.\n', '\n', 'Main API\n', '========\n', 'run(...): Runs a command, waits for it to complete, then returns a\n', '          CompletedProcess instance.\n', 'Popen(...): A class for flexibly executing a command in a new process\n', '\n', 'Constants\n', '---------\n', 'DEVNULL: Special value that indicates that os.devnull should be used\n', 'PIPE:    Special value that indicates a pipe should be created\n', 'STDOUT:  Special value that indicates that stderr should go to stdout\n', '\n', '\n', 'Older API\n', '=========\n', 'call(...): Runs a command, waits for it to complete, then returns\n', '    the return code.\n', 'check_call(...): Same as call() but raises CalledProcessError()\n', '    if return code is not 0\n', 'check_output(...): Same as check_call() but returns the contents of\n', '    stdout instead of a return code\n', 'getoutput(...): Runs a command in the shell, waits for it to complete,\n', '    then returns the output\n', 'getstatusoutput(...): Runs a command in the shell, waits for it to complete,\n', '    then returns a (exitcode, output) tuple\n', '"""\n', '\n', 'import builtins\n', 'import errno\n', 'import io\n', 'import os\n', 'import time\n', 'import signal\n', 'import sys\n', 'import threading\n', 'import warnings\n', 'import contextlib\n', 'from time import monotonic as _time\n', 'import types\n', '\n', 'try:\n', '    import fcntl\n', 'except ImportError:\n', '    fcntl = None\n', '\n', '\n', '__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",\n', '           "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL",\n', '           "SubprocessError", "TimeoutExpired", "CompletedProcess"]\n', '           # NOTE: We intentionally exclude list2cmdline as it is\n', '           # considered an internal implementation detail.  issue10838.\n', '\n', 'try:\n', '    import msvcrt\n', '    import _winapi\n', '    _mswindows = True\n', 'except ModuleNotFoundError:\n', '    _mswindows = False\n', '    import _posixsubprocess\n', '    import select\n', '    import selectors\n', 'else:\n', '    from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,\n', '                         STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,\n', '                         STD_ERROR_HANDLE, SW_HIDE,\n', '                         STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW,\n', '                         ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,\n', '                         HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS,\n', '                         NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS,\n', '                         CREATE_NO_WINDOW, DETACHED_PROCESS,\n', '                         CREATE_DEFAULT_ERROR_MODE, CREATE_BREAKAWAY_FROM_JOB)\n', '\n', '    __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP",\n', '                    "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE",\n', '                    "STD_ERROR_HANDLE", "SW_HIDE",\n', '                    "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW",\n', '                    "STARTUPINFO",\n', '                    "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",\n', '                    "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",\n', '                    "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",\n', '                    "CREATE_NO_WINDOW", "DETACHED_PROCESS",\n', '                    "CREATE_DEFAULT_ERROR_MODE", "CREATE_BREAKAWAY_FROM_JOB"])\n', '\n', '\n', '# Exception classes used by this module.\n', 'class SubprocessError(Exception): pass\n', '\n', '\n', 'class CalledProcessError(SubprocessError):\n', '    """Raised when run() is called with check=True and the process\n', '    returns a non-zero exit status.\n', '\n', '    Attributes:\n', '      cmd, returncode, stdout, stderr, output\n', '    """\n', '    def __init__(self, returncode, cmd, output=None, stderr=None):\n', '        self.returncode = returncode\n', '        self.cmd = cmd\n', '        self.output = output\n', '        self.stderr = stderr\n', '\n', '    def __str__(self):\n', '        if self.returncode and self.returncode < 0:\n', '            try:\n', '                return "Command \'%s\' died with %r." % (\n', '                        self.cmd, signal.Signals(-self.returncode))\n', '            except ValueError:\n', '                return "Command \'%s\' died with unknown signal %d." % (\n', '                        self.cmd, -self.returncode)\n', '        else:\n', '            return "Command \'%s\' returned non-zero exit status %d." % (\n', '                    self.cmd, self.returncode)\n', '\n', '    @property\n', '    def stdout(self):\n', '        """Alias for output attribute, to match stderr"""\n', '        return self.output\n', '\n', '    @stdout.setter\n', '    def stdout(self, value):\n', "        # There's no obvious reason to set this, but allow it anyway so\n", '        # .stdout is a transparent alias for .output\n', '        self.output = value\n', '\n', '\n', 'class TimeoutExpired(SubprocessError):\n', '    """This exception is raised when the timeout expires while waiting for a\n', '    child process.\n', '\n', '    Attributes:\n', '        cmd, output, stdout, stderr, timeout\n', '    """\n', '    def __init__(self, cmd, timeout, output=None, stderr=None):\n', '        self.cmd = cmd\n', '        self.timeout = timeout\n', '        self.output = output\n', '        self.stderr = stderr\n', '\n', '    def __str__(self):\n', '        return ("Command \'%s\' timed out after %s seconds" %\n', '                (self.cmd, self.timeout))\n', '\n', '    @property\n', '    def stdout(self):\n', '        return self.output\n', '\n', '    @stdout.setter\n', '    def stdout(self, value):\n', "        # There's no obvious reason to set this, but allow it anyway so\n", '        # .stdout is a transparent alias for .output\n', '        self.output = value\n', '\n', '\n', 'if _mswindows:\n', '    class STARTUPINFO:\n', '        def __init__(self, *, dwFlags=0, hStdInput=None, hStdOutput=None,\n', '                     hStdError=None, wShowWindow=0, lpAttributeList=None):\n', '            self.dwFlags = dwFlags\n', '            self.hStdInput = hStdInput\n', '            self.hStdOutput = hStdOutput\n', '            self.hStdError = hStdError\n', '            self.wShowWindow = wShowWindow\n', '            self.lpAttributeList = lpAttributeList or {"handle_list": []}\n', '\n', '        def copy(self):\n', '            attr_list = self.lpAttributeList.copy()\n', "            if 'handle_list' in attr_list:\n", "                attr_list['handle_list'] = list(attr_list['handle_list'])\n", '\n', '            return STARTUPINFO(dwFlags=self.dwFlags,\n', '                               hStdInput=self.hStdInput,\n', '                               hStdOutput=self.hStdOutput,\n', '                               hStdError=self.hStdError,\n', '                               wShowWindow=self.wShowWindow,\n', '                               lpAttributeList=attr_list)\n', '\n', '\n', '    class Handle(int):\n', '        closed = False\n', '\n', '        def Close(self, CloseHandle=_winapi.CloseHandle):\n', '            if not self.closed:\n', '                self.closed = True\n', '                CloseHandle(self)\n', '\n', '        def Detach(self):\n', '            if not self.closed:\n', '                self.closed = True\n', '                return int(self)\n', '            raise ValueError("already closed")\n', '\n', '        def __repr__(self):\n', '            return "%s(%d)" % (self.__class__.__name__, int(self))\n', '\n', '        __del__ = Close\n', 'else:\n', '    # When select or poll has indicated that the file is writable,\n', '    # we can write up to _PIPE_BUF bytes without risk of blocking.\n', '    # POSIX defines PIPE_BUF as >= 512.\n', "    _PIPE_BUF = getattr(select, 'PIPE_BUF', 512)\n", '\n', '    # poll/select have the advantage of not requiring any extra file\n', '    # descriptor, contrarily to epoll/kqueue (also, they require a single\n', '    # syscall).\n', "    if hasattr(selectors, 'PollSelector'):\n", '        _PopenSelector = selectors.PollSelector\n', '    else:\n', '        _PopenSelector = selectors.SelectSelector\n', '\n', '\n', 'if _mswindows:\n', '    # On Windows we just need to close `Popen._handle` when we no longer need\n', '    # it, so that the kernel can free it. `Popen._handle` gets closed\n', '    # implicitly when the `Popen` instance is finalized (see `Handle.__del__`,\n', '    # which is calling `CloseHandle` as requested in [1]), so there is nothing\n', '    # for `_cleanup` to do.\n', '    #\n', '    # [1] https://docs.microsoft.com/en-us/windows/desktop/ProcThread/\n', '    # creating-processes\n', '    _active = None\n', '\n', '    def _cleanup():\n', '        pass\n', 'else:\n', '    # This lists holds Popen instances for which the underlying process had not\n', '    # exited at the time its __del__ method got called: those processes are\n', '    # wait()ed for synchronously from _cleanup() when a new Popen object is\n', '    # created, to avoid zombie processes.\n', '    _active = []\n', '\n', '    def _cleanup():\n', '        if _active is None:\n', '            return\n', '        for inst in _active[:]:\n', '            res = inst._internal_poll(_deadstate=sys.maxsize)\n', '            if res is not None:\n', '                try:\n', '                    _active.remove(inst)\n', '                except ValueError:\n', '                    # This can happen if two threads create a new Popen instance.\n', "                    # It's harmless that it was already removed, so ignore.\n", '                    pass\n', '\n', 'PIPE = -1\n', 'STDOUT = -2\n', 'DEVNULL = -3\n', '\n', '\n', '# XXX This function is only used by multiprocessing and the test suite,\n', "# but it's here so that it can be imported when Python is compiled without\n", '# threads.\n', '\n', 'def _optim_args_from_interpreter_flags():\n', '    """Return a list of command-line arguments reproducing the current\n', '    optimization settings in sys.flags."""\n', '    args = []\n', '    value = sys.flags.optimize\n', '    if value > 0:\n', "        args.append('-' + 'O' * value)\n", '    return args\n', '\n', '\n', 'def _args_from_interpreter_flags():\n', '    """Return a list of command-line arguments reproducing the current\n', '    settings in sys.flags, sys.warnoptions and sys._xoptions."""\n', '    flag_opt_map = {\n', "        'debug': 'd',\n", "        # 'inspect': 'i',\n", "        # 'interactive': 'i',\n", "        'dont_write_bytecode': 'B',\n", "        'no_site': 'S',\n", "        'verbose': 'v',\n", "        'bytes_warning': 'b',\n", "        'quiet': 'q',\n", '        # -O is handled in _optim_args_from_interpreter_flags()\n', '    }\n', '    args = _optim_args_from_interpreter_flags()\n', '    for flag, opt in flag_opt_map.items():\n', '        v = getattr(sys.flags, flag)\n', '        if v > 0:\n', "            args.append('-' + opt * v)\n", '\n', '    if sys.flags.isolated:\n', "        args.append('-I')\n", '    else:\n', '        if sys.flags.ignore_environment:\n', "            args.append('-E')\n", '        if sys.flags.no_user_site:\n', "            args.append('-s')\n", '\n', '    # -W options\n', '    warnopts = sys.warnoptions[:]\n', '    bytes_warning = sys.flags.bytes_warning\n', "    xoptions = getattr(sys, '_xoptions', {})\n", "    dev_mode = ('dev' in xoptions)\n", '\n', '    if bytes_warning > 1:\n', '        warnopts.remove("error::BytesWarning")\n', '    elif bytes_warning:\n', '        warnopts.remove("default::BytesWarning")\n', '    if dev_mode:\n', "        warnopts.remove('default')\n", '    for opt in warnopts:\n', "        args.append('-W' + opt)\n", '\n', '    # -X options\n', '    if dev_mode:\n', "        args.extend(('-X', 'dev'))\n", "    for opt in ('faulthandler', 'tracemalloc', 'importtime',\n", "                'showrefcount', 'utf8'):\n", '        if opt in xoptions:\n', '            value = xoptions[opt]\n', '            if value is True:\n', '                arg = opt\n', '            else:\n', "                arg = '%s=%s' % (opt, value)\n", "            args.extend(('-X', arg))\n", '\n', '    return args\n', '\n', '\n', 'def call(*popenargs, timeout=None, **kwargs):\n', '    """Run command with arguments.  Wait for command to complete or\n', '    timeout, then return the returncode attribute.\n', '\n', '    The arguments are the same as for the Popen constructor.  Example:\n', '\n', '    retcode = call(["ls", "-l"])\n', '    """\n', '    with Popen(*popenargs, **kwargs) as p:\n', '        try:\n', '            return p.wait(timeout=timeout)\n', '        except:  # Including KeyboardInterrupt, wait handled that.\n', '            p.kill()\n', "            # We don't call p.wait() again as p.__exit__ does that for us.\n", '            raise\n', '\n', '\n', 'def check_call(*popenargs, **kwargs):\n', '    """Run command with arguments.  Wait for command to complete.  If\n', '    the exit code was zero then return, otherwise raise\n', '    CalledProcessError.  The CalledProcessError object will have the\n', '    return code in the returncode attribute.\n', '\n', '    The arguments are the same as for the call function.  Example:\n', '\n', '    check_call(["ls", "-l"])\n', '    """\n', '    retcode = call(*popenargs, **kwargs)\n', '    if retcode:\n', '        cmd = kwargs.get("args")\n', '        if cmd is None:\n', '            cmd = popenargs[0]\n', '        raise CalledProcessError(retcode, cmd)\n', '    return 0\n', '\n', '\n', 'def check_output(*popenargs, timeout=None, **kwargs):\n', '    r"""Run command with arguments and return its output.\n', '\n', '    If the exit code was non-zero it raises a CalledProcessError.  The\n', '    CalledProcessError object will have the return code in the returncode\n', '    attribute and output in the output attribute.\n', '\n', '    The arguments are the same as for the Popen constructor.  Example:\n', '\n', '    >>> check_output(["ls", "-l", "/dev/null"])\n', "    b'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\\n'\n", '\n', '    The stdout argument is not allowed as it is used internally.\n', '    To capture standard error in the result, use stderr=STDOUT.\n', '\n', '    >>> check_output(["/bin/sh", "-c",\n', '    ...               "ls -l non_existent_file ; exit 0"],\n', '    ...              stderr=STDOUT)\n', "    b'ls: non_existent_file: No such file or directory\\n'\n", '\n', '    There is an additional optional argument, "input", allowing you to\n', "    pass a string to the subprocess's stdin.  If you use this argument\n", '    you may not also use the Popen constructor\'s "stdin" argument, as\n', '    it too will be used internally.  Example:\n', '\n', '    >>> check_output(["sed", "-e", "s/foo/bar/"],\n', '    ...              input=b"when in the course of fooman events\\n")\n', "    b'when in the course of barman events\\n'\n", '\n', '    By default, all communication is in bytes, and therefore any "input"\n', '    should be bytes, and the return value will be bytes.  If in text mode,\n', '    any "input" should be a string, and the return value will be a string\n', '    decoded according to locale encoding, or by "encoding" if set. Text mode\n', '    is triggered by setting any of text, encoding, errors or universal_newlines.\n', '    """\n', "    if 'stdout' in kwargs:\n", "        raise ValueError('stdout argument not allowed, it will be overridden.')\n", '\n', "    if 'input' in kwargs and kwargs['input'] is None:\n", '        # Explicitly passing input=None was previously equivalent to passing an\n', '        # empty string. That is maintained here for backwards compatibility.\n', "        if kwargs.get('universal_newlines') or kwargs.get('text') or kwargs.get('encoding') \\\n", "                or kwargs.get('errors'):\n", "            empty = ''\n", '        else:\n', "            empty = b''\n", "        kwargs['input'] = empty\n", '\n', '    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,\n', '               **kwargs).stdout\n', '\n', '\n', 'class CompletedProcess(object):\n', '    """A process that has finished running.\n', '\n', '    This is returned by run().\n', '\n', '    Attributes:\n', '      args: The list or str args passed to run().\n', '      returncode: The exit code of the process, negative for signals.\n', '      stdout: The standard output (None if not captured).\n', '      stderr: The standard error (None if not captured).\n', '    """\n', '    def __init__(self, args, returncode, stdout=None, stderr=None):\n', '        self.args = args\n', '        self.returncode = returncode\n', '        self.stdout = stdout\n', '        self.stderr = stderr\n', '\n', '    def __repr__(self):\n', "        args = ['args={!r}'.format(self.args),\n", "                'returncode={!r}'.format(self.returncode)]\n", '        if self.stdout is not None:\n', "            args.append('stdout={!r}'.format(self.stdout))\n", '        if self.stderr is not None:\n', "            args.append('stderr={!r}'.format(self.stderr))\n", '        return "{}({})".format(type(self).__name__, \', \'.join(args))\n', '\n', '    __class_getitem__ = classmethod(types.GenericAlias)\n', '\n', '\n', '    def check_returncode(self):\n', '        """Raise CalledProcessError if the exit code is non-zero."""\n', '        if self.returncode:\n', '            raise CalledProcessError(self.returncode, self.args, self.stdout,\n', '                                     self.stderr)\n', '\n', '\n', 'def run(*popenargs,\n', '        input=None, capture_output=False, timeout=None, check=False, **kwargs):\n', '    """Run command with arguments and return a CompletedProcess instance.\n', '\n', '    The returned instance will have attributes args, returncode, stdout and\n', '    stderr. By default, stdout and stderr are not captured, and those attributes\n', '    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,\n', '    or pass capture_output=True to capture both.\n', '\n', '    If check is True and the exit code was non-zero, it raises a\n', '    CalledProcessError. The CalledProcessError object will have the return code\n', '    in the returncode attribute, and output & stderr attributes if those streams\n', '    were captured.\n', '\n', '    If timeout is given, and the process takes too long, a TimeoutExpired\n', '    exception will be raised.\n', '\n', '    There is an optional argument "input", allowing you to\n', "    pass bytes or a string to the subprocess's stdin.  If you use this argument\n", '    you may not also use the Popen constructor\'s "stdin" argument, as\n', '    it will be used internally.\n', '\n', '    By default, all communication is in bytes, and therefore any "input" should\n', '    be bytes, and the stdout and stderr will be bytes. If in text mode, any\n', '    "input" should be a string, and stdout and stderr will be strings decoded\n', '    according to locale encoding, or by "encoding" if set. Text mode is\n', '    triggered by setting any of text, encoding, errors or universal_newlines.\n', '\n', '    The other arguments are the same as for the Popen constructor.\n', '    """\n', '    if input is not None:\n', "        if kwargs.get('stdin') is not None:\n", "            raise ValueError('stdin and input arguments may not both be used.')\n", "        kwargs['stdin'] = PIPE\n", '\n', '    if capture_output:\n', "        if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:\n", "            raise ValueError('stdout and stderr arguments may not be used '\n", "                             'with capture_output.')\n", "        kwargs['stdout'] = PIPE\n", "        kwargs['stderr'] = PIPE\n", '\n', '    with Popen(*popenargs, **kwargs) as process:\n', '        try:\n', '            stdout, stderr = process.communicate(input, timeout=timeout)\n', '        except TimeoutExpired as exc:\n', '            process.kill()\n', '            if _mswindows:\n', '                # Windows accumulates the output in a single blocking\n', '                # read() call run on child threads, with the timeout\n', '                # being done in a join() on those threads.  communicate()\n', '                # _after_ kill() is required to collect that and add it\n', '                # to the exception.\n', '                exc.stdout, exc.stderr = process.communicate()\n', '            else:\n', '                # POSIX _communicate already populated the output so\n', '                # far into the TimeoutExpired exception.\n', '                process.wait()\n', '            raise\n', '        except:  # Including KeyboardInterrupt, communicate handled that.\n', '            process.kill()\n', "            # We don't call process.wait() as .__exit__ does that for us.\n", '            raise\n', '        retcode = process.poll()\n', '        if check and retcode:\n', '            raise CalledProcessError(retcode, process.args,\n', '                                     output=stdout, stderr=stderr)\n', '    return CompletedProcess(process.args, retcode, stdout, stderr)\n', '\n', '\n', 'def list2cmdline(seq):\n', '    """\n', '    Translate a sequence of arguments into a command line\n', '    string, using the same rules as the MS C runtime:\n', '\n', '    1) Arguments are delimited by white space, which is either a\n', '       space or a tab.\n', '\n', '    2) A string surrounded by double quotation marks is\n', '       interpreted as a single argument, regardless of white space\n', '       contained within.  A quoted string can be embedded in an\n', '       argument.\n', '\n', '    3) A double quotation mark preceded by a backslash is\n', '       interpreted as a literal double quotation mark.\n', '\n', '    4) Backslashes are interpreted literally, unless they\n', '       immediately precede a double quotation mark.\n', '\n', '    5) If backslashes immediately precede a double quotation mark,\n', '       every pair of backslashes is interpreted as a literal\n', '       backslash.  If the number of backslashes is odd, the last\n', '       backslash escapes the next double quotation mark as\n', '       described in rule 3.\n', '    """\n', '\n', '    # See\n', '    # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx\n', '    # or search http://msdn.microsoft.com for\n', '    # "Parsing C++ Command-Line Arguments"\n', '    result = []\n', '    needquote = False\n', '    for arg in map(os.fsdecode, seq):\n', '        bs_buf = []\n', '\n', '        # Add a space to separate this argument from the others\n', '        if result:\n', "            result.append(' ')\n", '\n', '        needquote = (" " in arg) or ("\\t" in arg) or not arg\n', '        if needquote:\n', '            result.append(\'"\')\n', '\n', '        for c in arg:\n', "            if c == '\\\\':\n", "                # Don't know if we need to double yet.\n", '                bs_buf.append(c)\n', '            elif c == \'"\':\n', '                # Double backslashes.\n', "                result.append('\\\\' * len(bs_buf)*2)\n", '                bs_buf = []\n', '                result.append(\'\\\\"\')\n', '            else:\n', '                # Normal char\n', '                if bs_buf:\n', '                    result.extend(bs_buf)\n', '                    bs_buf = []\n', '                result.append(c)\n', '\n', '        # Add remaining backslashes, if any.\n', '        if bs_buf:\n', '            result.extend(bs_buf)\n', '\n', '        if needquote:\n', '            result.extend(bs_buf)\n', '            result.append(\'"\')\n', '\n', "    return ''.join(result)\n", '\n', '\n', '# Various tools for executing commands and looking at their output and status.\n', '#\n', '\n', 'def getstatusoutput(cmd):\n', '    """Return (exitcode, output) of executing cmd in a shell.\n', '\n', "    Execute the string 'cmd' in a shell with 'check_output' and\n", '    return a 2-tuple (status, output). The locale encoding is used\n', '    to decode the output and process newlines.\n', '\n', '    A trailing newline is stripped from the output.\n', '    The exit status for the command can be interpreted\n', "    according to the rules for the function 'wait'. Example:\n", '\n', '    >>> import subprocess\n', "    >>> subprocess.getstatusoutput('ls /bin/ls')\n", "    (0, '/bin/ls')\n", "    >>> subprocess.getstatusoutput('cat /bin/junk')\n", "    (1, 'cat: /bin/junk: No such file or directory')\n", "    >>> subprocess.getstatusoutput('/bin/junk')\n", "    (127, 'sh: /bin/junk: not found')\n", "    >>> subprocess.getstatusoutput('/bin/kill $')\n", "    (-15, '')\n", '    """\n', '    try:\n', '        data = check_output(cmd, shell=True, text=True, stderr=STDOUT)\n', '        exitcode = 0\n', '    except CalledProcessError as ex:\n', '        data = ex.output\n', '        exitcode = ex.returncode\n', "    if data[-1:] == '\\n':\n", '        data = data[:-1]\n', '    return exitcode, data\n', '\n', 'def getoutput(cmd):\n', '    """Return output (stdout or stderr) of executing cmd in a shell.\n', '\n', '    Like getstatusoutput(), except the exit status is ignored and the return\n', "    value is a string containing the command's output.  Example:\n", '\n', '    >>> import subprocess\n', "    >>> subprocess.getoutput('ls /bin/ls')\n", "    '/bin/ls'\n", '    """\n', '    return getstatusoutput(cmd)[1]\n', '\n', '\n', 'def _use_posix_spawn():\n', '    """Check if posix_spawn() can be used for subprocess.\n', '\n', '    subprocess requires a posix_spawn() implementation that properly reports\n', '    errors to the parent process, & sets errno on the following failures:\n', '\n', '    * Process attribute actions failed.\n', '    * File actions failed.\n', '    * exec() failed.\n', '\n', '    Prefer an implementation which can use vfork() in some cases for best\n', '    performance.\n', '    """\n', "    if _mswindows or not hasattr(os, 'posix_spawn'):\n", '        # os.posix_spawn() is not available\n', '        return False\n', '\n', "    if sys.platform in ('darwin', 'sunos5'):\n", '        # posix_spawn() is a syscall on both macOS and Solaris,\n', '        # and properly reports errors\n', '        return True\n', '\n', '    # Check libc name and runtime libc version\n', '    try:\n', "        ver = os.confstr('CS_GNU_LIBC_VERSION')\n", "        # parse 'glibc 2.28' as ('glibc', (2, 28))\n", '        parts = ver.split(maxsplit=1)\n', '        if len(parts) != 2:\n', '            # reject unknown format\n', '            raise ValueError\n', '        libc = parts[0]\n', "        version = tuple(map(int, parts[1].split('.')))\n", '\n', "        if sys.platform == 'linux' and libc == 'glibc' and version >= (2, 24):\n", '            # glibc 2.24 has a new Linux posix_spawn implementation using vfork\n', '            # which properly reports errors to the parent process.\n', '            return True\n', "        # Note: Don't use the implementation in earlier glibc because it doesn't\n", '        # use vfork (even if glibc 2.26 added a pipe to properly report errors\n', '        # to the parent process).\n', '    except (AttributeError, ValueError, OSError):\n', '        # os.confstr() or CS_GNU_LIBC_VERSION value not available\n', '        pass\n', '\n', '    # By default, assume that posix_spawn() does not properly report errors.\n', '    return False\n', '\n', '\n', '# These are primarily fail-safe knobs for negatives. A True value does not\n', '# guarantee the given libc/syscall API will be used.\n', '_USE_POSIX_SPAWN = _use_posix_spawn()\n', '_USE_VFORK = True\n', '\n', '\n', 'class Popen:\n', '    """ Execute a child program in a new process.\n', '\n', '    For a complete description of the arguments see the Python documentation.\n', '\n', '    Arguments:\n', '      args: A string, or a sequence of program arguments.\n', '\n', '      bufsize: supplied as the buffering argument to the open() function when\n', '          creating the stdin/stdout/stderr pipe file objects\n', '\n', '      executable: A replacement program to execute.\n', '\n', "      stdin, stdout and stderr: These specify the executed programs' standard\n", '          input, standard output and standard error file handles, respectively.\n', '\n', '      preexec_fn: (POSIX only) An object to be called in the child process\n', '          just before the child is executed.\n', '\n', '      close_fds: Controls closing or inheriting of file descriptors.\n', '\n', '      shell: If true, the command will be executed through the shell.\n', '\n', '      cwd: Sets the current directory before the child is executed.\n', '\n', '      env: Defines the environment variables for the new process.\n', '\n', '      text: If true, decode stdin, stdout and stderr using the given encoding\n', '          (if set) or the system default otherwise.\n', '\n', '      universal_newlines: Alias of text, provided for backwards compatibility.\n', '\n', '      startupinfo and creationflags (Windows only)\n', '\n', '      restore_signals (POSIX only)\n', '\n', '      start_new_session (POSIX only)\n', '\n', '      group (POSIX only)\n', '\n', '      extra_groups (POSIX only)\n', '\n', '      user (POSIX only)\n', '\n', '      umask (POSIX only)\n', '\n', '      pass_fds (POSIX only)\n', '\n', '      encoding and errors: Text mode encoding and error handling to use for\n', '          file objects stdin, stdout and stderr.\n', '\n', '    Attributes:\n', '        stdin, stdout, stderr, pid, returncode\n', '    """\n', '    _child_created = False  # Set here since __del__ checks it\n', '\n', '    def __init__(self, args, bufsize=-1, executable=None,\n', '                 stdin=None, stdout=None, stderr=None,\n', '                 preexec_fn=None, close_fds=True,\n', '                 shell=False, cwd=None, env=None, universal_newlines=None,\n', '                 startupinfo=None, creationflags=0,\n', '                 restore_signals=True, start_new_session=False,\n', '                 pass_fds=(), *, user=None, group=None, extra_groups=None,\n', '                 encoding=None, errors=None, text=None, umask=-1, pipesize=-1):\n', '        """Create new Popen instance."""\n', '        _cleanup()\n', '        # Held while anything is calling waitpid before returncode has been\n', '        # updated to prevent clobbering returncode if wait() or poll() are\n', '        # called from multiple threads at once.  After acquiring the lock,\n', '        # code must re-check self.returncode to see if another thread just\n', '        # finished a waitpid() call.\n', '        self._waitpid_lock = threading.Lock()\n', '\n', '        self._input = None\n', '        self._communication_started = False\n', '        if bufsize is None:\n', '            bufsize = -1  # Restore default\n', '        if not isinstance(bufsize, int):\n', '            raise TypeError("bufsize must be an integer")\n', '\n', '        if pipesize is None:\n', '            pipesize = -1  # Restore default\n', '        if not isinstance(pipesize, int):\n', '            raise TypeError("pipesize must be an integer")\n', '\n', '        if _mswindows:\n', '            if preexec_fn is not None:\n', '                raise ValueError("preexec_fn is not supported on Windows "\n', '                                 "platforms")\n', '        else:\n', '            # POSIX\n', '            if pass_fds and not close_fds:\n', '                warnings.warn("pass_fds overriding close_fds.", RuntimeWarning)\n', '                close_fds = True\n', '            if startupinfo is not None:\n', '                raise ValueError("startupinfo is only supported on Windows "\n', '                                 "platforms")\n', '            if creationflags != 0:\n', '                raise ValueError("creationflags is only supported on Windows "\n', '                                 "platforms")\n', '\n', '        self.args = args\n', '        self.stdin = None\n', '        self.stdout = None\n', '        self.stderr = None\n', '        self.pid = None\n', '        self.returncode = None\n', '        self.encoding = encoding\n', '        self.errors = errors\n', '        self.pipesize = pipesize\n', '\n', '        # Validate the combinations of text and universal_newlines\n', '        if (text is not None and universal_newlines is not None\n', '            and bool(universal_newlines) != bool(text)):\n', "            raise SubprocessError('Cannot disambiguate when both text '\n", "                                  'and universal_newlines are supplied but '\n", "                                  'different. Pass one or the other.')\n", '\n', '        # Input and output objects. The general principle is like\n', '        # this:\n', '        #\n', '        # Parent                   Child\n', '        # ------                   -----\n', '        # p2cwrite   ---stdin--->  p2cread\n', '        # c2pread    <--stdout---  c2pwrite\n', '        # errread    <--stderr---  errwrite\n', '        #\n', '        # On POSIX, the child objects are file descriptors.  On\n', '        # Windows, these are Windows file handles.  The parent objects\n', '        # are file descriptors on both platforms.  The parent objects\n', '        # are -1 when not using PIPEs. The child objects are -1\n', '        # when not redirecting.\n', '\n', '        (p2cread, p2cwrite,\n', '         c2pread, c2pwrite,\n', '         errread, errwrite) = self._get_handles(stdin, stdout, stderr)\n', '\n', '        # We wrap OS handles *before* launching the child, otherwise a\n', '        # quickly terminating child could make our fds unwrappable\n', '        # (see #8458).\n', '\n', '        if _mswindows:\n', '            if p2cwrite != -1:\n', '                p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0)\n', '            if c2pread != -1:\n', '                c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0)\n', '            if errread != -1:\n', '                errread = msvcrt.open_osfhandle(errread.Detach(), 0)\n', '\n', '        self.text_mode = encoding or errors or text or universal_newlines\n', '\n', '        # PEP 597: We suppress the EncodingWarning in subprocess module\n', '        # for now (at Python 3.10), because we focus on files for now.\n', '        # This will be changed to encoding = io.text_encoding(encoding)\n', '        # in the future.\n', '        if self.text_mode and encoding is None:\n', '            self.encoding = encoding = "locale"\n', '\n', '        # How long to resume waiting on a child after the first ^C.\n', '        # There is no right value for this.  The purpose is to be polite\n', '        # yet remain good for interactive users trying to exit a tool.\n', '        self._sigint_wait_secs = 0.25  # 1/xkcd221.getRandomNumber()\n', '\n', '        self._closed_child_pipe_fds = False\n', '\n', '        if self.text_mode:\n', '            if bufsize == 1:\n', '                line_buffering = True\n', '                # Use the default buffer size for the underlying binary streams\n', "                # since they don't support line buffering.\n", '                bufsize = -1\n', '            else:\n', '                line_buffering = False\n', '\n', '        gid = None\n', '        if group is not None:\n', "            if not hasattr(os, 'setregid'):\n", '                raise ValueError("The \'group\' parameter is not supported on the "\n', '                                 "current platform")\n', '\n', '            elif isinstance(group, str):\n', '                try:\n', '                    import grp\n', '                except ImportError:\n', '                    raise ValueError("The group parameter cannot be a string "\n', '                                     "on systems without the grp module")\n', '\n', '                gid = grp.getgrnam(group).gr_gid\n', '            elif isinstance(group, int):\n', '                gid = group\n', '            else:\n', '                raise TypeError("Group must be a string or an integer, not {}"\n', '                                .format(type(group)))\n', '\n', '            if gid < 0:\n', '                raise ValueError(f"Group ID cannot be negative, got {gid}")\n', '\n', '        gids = None\n', '        if extra_groups is not None:\n', "            if not hasattr(os, 'setgroups'):\n", '                raise ValueError("The \'extra_groups\' parameter is not "\n', '                                 "supported on the current platform")\n', '\n', '            elif isinstance(extra_groups, str):\n', '                raise ValueError("Groups must be a list, not a string")\n', '\n', '            gids = []\n', '            for extra_group in extra_groups:\n', '                if isinstance(extra_group, str):\n', '                    try:\n', '                        import grp\n', '                    except ImportError:\n', '                        raise ValueError("Items in extra_groups cannot be "\n', '                                         "strings on systems without the "\n', '                                         "grp module")\n', '\n', '                    gids.append(grp.getgrnam(extra_group).gr_gid)\n', '                elif isinstance(extra_group, int):\n', '                    gids.append(extra_group)\n', '                else:\n', '                    raise TypeError("Items in extra_groups must be a string "\n', '                                    "or integer, not {}"\n', '                                    .format(type(extra_group)))\n', '\n', '            # make sure that the gids are all positive here so we can do less\n', '            # checking in the C code\n', '            for gid_check in gids:\n', '                if gid_check < 0:\n', '                    raise ValueError(f"Group ID cannot be negative, got {gid_check}")\n', '\n', '        uid = None\n', '        if user is not None:\n', "            if not hasattr(os, 'setreuid'):\n", '                raise ValueError("The \'user\' parameter is not supported on "\n', '                                 "the current platform")\n', '\n', '            elif isinstance(user, str):\n', '                try:\n', '                    import pwd\n', '                except ImportError:\n', '                    raise ValueError("The user parameter cannot be a string "\n', '                                     "on systems without the pwd module")\n', '                uid = pwd.getpwnam(user).pw_uid\n', '            elif isinstance(user, int):\n', '                uid = user\n', '            else:\n', '                raise TypeError("User must be a string or an integer")\n', '\n', '            if uid < 0:\n', '                raise ValueError(f"User ID cannot be negative, got {uid}")\n', '\n', '        try:\n', '            if p2cwrite != -1:\n', "                self.stdin = io.open(p2cwrite, 'wb', bufsize)\n", '                if self.text_mode:\n', '                    self.stdin = io.TextIOWrapper(self.stdin, write_through=True,\n', '                            line_buffering=line_buffering,\n', '                            encoding=encoding, errors=errors)\n', '            if c2pread != -1:\n', "                self.stdout = io.open(c2pread, 'rb', bufsize)\n", '                if self.text_mode:\n', '                    self.stdout = io.TextIOWrapper(self.stdout,\n', '                            encoding=encoding, errors=errors)\n', '            if errread != -1:\n', "                self.stderr = io.open(errread, 'rb', bufsize)\n", '                if self.text_mode:\n', '                    self.stderr = io.TextIOWrapper(self.stderr,\n', '                            encoding=encoding, errors=errors)\n', '\n', '            self._execute_child(args, executable, preexec_fn, close_fds,\n', '                                pass_fds, cwd, env,\n', '                                startupinfo, creationflags, shell,\n', '                                p2cread, p2cwrite,\n', '                                c2pread, c2pwrite,\n', '                                errread, errwrite,\n', '                                restore_signals,\n', '                                gid, gids, uid, umask,\n', '                                start_new_session)\n', '        except:\n', '            # Cleanup if the child failed starting.\n', '            for f in filter(None, (self.stdin, self.stdout, self.stderr)):\n', '                try:\n', '                    f.close()\n', '                except OSError:\n', '                    pass  # Ignore EBADF or other errors.\n', '\n', '            if not self._closed_child_pipe_fds:\n', '                to_close = []\n', '                if stdin == PIPE:\n', '                    to_close.append(p2cread)\n', '                if stdout == PIPE:\n', '                    to_close.append(c2pwrite)\n', '                if stderr == PIPE:\n', '                    to_close.append(errwrite)\n', "                if hasattr(self, '_devnull'):\n", '                    to_close.append(self._devnull)\n', '                for fd in to_close:\n', '                    try:\n', '                        if _mswindows and isinstance(fd, Handle):\n', '                            fd.Close()\n', '                        else:\n', '                            os.close(fd)\n', '                    except OSError:\n', '                        pass\n', '\n', '            raise\n', '\n', '    def __repr__(self):\n', '        obj_repr = (\n', '            f"<{self.__class__.__name__}: "\n', '            f"returncode: {self.returncode} args: {self.args!r}>"\n', '        )\n', '        if len(obj_repr) > 80:\n', '            obj_repr = obj_repr[:76] + "...>"\n', '        return obj_repr\n', '\n', '    __class_getitem__ = classmethod(types.GenericAlias)\n', '\n', '    @property\n', '    def universal_newlines(self):\n', '        # universal_newlines as retained as an alias of text_mode for API\n', '        # compatibility. bpo-31756\n', '        return self.text_mode\n', '\n', '    @universal_newlines.setter\n', '    def universal_newlines(self, universal_newlines):\n', '        self.text_mode = bool(universal_newlines)\n', '\n', '    def _translate_newlines(self, data, encoding, errors):\n', '        data = data.decode(encoding, errors)\n', '        return data.replace("\\r\\n", "\\n").replace("\\r", "\\n")\n', '\n', '    def __enter__(self):\n', '        return self\n', '\n', '    def __exit__(self, exc_type, value, traceback):\n', '        if self.stdout:\n', '            self.stdout.close()\n', '        if self.stderr:\n', '            self.stderr.close()\n', '        try:  # Flushing a BufferedWriter may raise an error\n', '            if self.stdin:\n', '                self.stdin.close()\n', '        finally:\n', '            if exc_type == KeyboardInterrupt:\n', '                # https://bugs.python.org/issue25942\n', '                # In the case of a KeyboardInterrupt we assume the SIGINT\n', "                # was also already sent to our child processes.  We can't\n", '                # block indefinitely as that is not user friendly.\n', '                # If we have not already waited a brief amount of time in\n', '                # an interrupted .wait() or .communicate() call, do so here\n', '                # for consistency.\n', '                if self._sigint_wait_secs > 0:\n', '                    try:\n', '                        self._wait(timeout=self._sigint_wait_secs)\n', '                    except TimeoutExpired:\n', '                        pass\n', '                self._sigint_wait_secs = 0  # Note that this has been done.\n', '                return  # resume the KeyboardInterrupt\n', '\n', '            # Wait for the process to terminate, to avoid zombies.\n', '            self.wait()\n', '\n', '    def __del__(self, _maxsize=sys.maxsize, _warn=warnings.warn):\n', '        if not self._child_created:\n', "            # We didn't get to successfully create a child process.\n", '            return\n', '        if self.returncode is None:\n', '            # Not reading subprocess exit status creates a zombie process which\n', '            # is only destroyed at the parent python process exit\n', '            _warn("subprocess %s is still running" % self.pid,\n', '                  ResourceWarning, source=self)\n', "        # In case the child hasn't been waited on, check if it's done.\n", '        self._internal_poll(_deadstate=_maxsize)\n', '        if self.returncode is None and _active is not None:\n', '            # Child is still running, keep us alive until we can wait on it.\n', '            _active.append(self)\n', '\n', '    def _get_devnull(self):\n', "        if not hasattr(self, '_devnull'):\n", '            self._devnull = os.open(os.devnull, os.O_RDWR)\n', '        return self._devnull\n', '\n', '    def _stdin_write(self, input):\n', '        if input:\n', '            try:\n', '                self.stdin.write(input)\n', '            except BrokenPipeError:\n', '                pass  # communicate() must ignore broken pipe errors.\n', '            except OSError as exc:\n', '                if exc.errno == errno.EINVAL:\n', '                    # bpo-19612, bpo-30418: On Windows, stdin.write() fails\n', '                    # with EINVAL if the child process exited or if the child\n', '                    # process is still running but closed the pipe.\n', '                    pass\n', '                else:\n', '                    raise\n', '\n', '        try:\n', '            self.stdin.close()\n', '        except BrokenPipeError:\n', '            pass  # communicate() must ignore broken pipe errors.\n', '        except OSError as exc:\n', '            if exc.errno == errno.EINVAL:\n', '                pass\n', '            else:\n', '                raise\n', '\n', '    def communicate(self, input=None, timeout=None):\n', '        """Interact with process: Send data to stdin and close it.\n', '        Read data from stdout and stderr, until end-of-file is\n', '        reached.  Wait for process to terminate.\n', '\n', '        The optional "input" argument should be data to be sent to the\n', '        child process, or None, if no data should be sent to the child.\n', '        communicate() returns a tuple (stdout, stderr).\n', '\n', '        By default, all communication is in bytes, and therefore any\n', '        "input" should be bytes, and the (stdout, stderr) will be bytes.\n', '        If in text mode (indicated by self.text_mode), any "input" should\n', '        be a string, and (stdout, stderr) will be strings decoded\n', '        according to locale encoding, or by "encoding" if set. Text mode\n', '        is triggered by setting any of text, encoding, errors or\n', '        universal_newlines.\n', '        """\n', '\n', '        if self._communication_started and input:\n', '            raise ValueError("Cannot send input after starting communication")\n', '\n', "        # Optimization: If we are not worried about timeouts, we haven't\n", '        # started communicating, and we have one or zero pipes, using select()\n', '        # or threads is unnecessary.\n', '        if (timeout is None and not self._communication_started and\n', '            [self.stdin, self.stdout, self.stderr].count(None) >= 2):\n', '            stdout = None\n', '            stderr = None\n', '            if self.stdin:\n', '                self._stdin_write(input)\n', '            elif self.stdout:\n', '                stdout = self.stdout.read()\n', '                self.stdout.close()\n', '            elif self.stderr:\n', '                stderr = self.stderr.read()\n', '                self.stderr.close()\n', '            self.wait()\n', '        else:\n', '            if timeout is not None:\n', '                endtime = _time() + timeout\n', '            else:\n', '                endtime = None\n', '\n', '            try:\n', '                stdout, stderr = self._communicate(input, endtime, timeout)\n', '            except KeyboardInterrupt:\n', '                # https://bugs.python.org/issue25942\n', '                # See the detailed comment in .wait().\n', '                if timeout is not None:\n', '                    sigint_timeout = min(self._sigint_wait_secs,\n', '                                         self._remaining_time(endtime))\n', '                else:\n', '                    sigint_timeout = self._sigint_wait_secs\n', '                self._sigint_wait_secs = 0  # nothing else should wait.\n', '                try:\n', '                    self._wait(timeout=sigint_timeout)\n', '                except TimeoutExpired:\n', '                    pass\n', '                raise  # resume the KeyboardInterrupt\n', '\n', '            finally:\n', '                self._communication_started = True\n', '\n', '            sts = self.wait(timeout=self._remaining_time(endtime))\n', '\n', '        return (stdout, stderr)\n', '\n', '\n', '    def poll(self):\n', '        """Check if child process has terminated. Set and return returncode\n', '        attribute."""\n', '        return self._internal_poll()\n', '\n', '\n', '    def _remaining_time(self, endtime):\n', '        """Convenience for _communicate when computing timeouts."""\n', '        if endtime is None:\n', '            return None\n', '        else:\n', '            return endtime - _time()\n', '\n', '\n', '    def _check_timeout(self, endtime, orig_timeout, stdout_seq, stderr_seq,\n', '                       skip_check_and_raise=False):\n', '        """Convenience for checking if a timeout has expired."""\n', '        if endtime is None:\n', '            return\n', '        if skip_check_and_raise or _time() > endtime:\n', '            raise TimeoutExpired(\n', '                    self.args, orig_timeout,\n', "                    output=b''.join(stdout_seq) if stdout_seq else None,\n", "                    stderr=b''.join(stderr_seq) if stderr_seq else None)\n", '\n', '\n', '    def wait(self, timeout=None):\n', '        """Wait for child process to terminate; returns self.returncode."""\n', '        if timeout is not None:\n', '            endtime = _time() + timeout\n', '        try:\n', '            return self._wait(timeout=timeout)\n', '        except KeyboardInterrupt:\n', '            # https://bugs.python.org/issue25942\n', '            # The first keyboard interrupt waits briefly for the child to\n', '            # exit under the common assumption that it also received the ^C\n', '            # generated SIGINT and will exit rapidly.\n', '            if timeout is not None:\n', '                sigint_timeout = min(self._sigint_wait_secs,\n', '                                     self._remaining_time(endtime))\n', '            else:\n', '                sigint_timeout = self._sigint_wait_secs\n', '            self._sigint_wait_secs = 0  # nothing else should wait.\n', '            try:\n', '                self._wait(timeout=sigint_timeout)\n', '            except TimeoutExpired:\n', '                pass\n', '            raise  # resume the KeyboardInterrupt\n', '\n', '    def _close_pipe_fds(self,\n', '                        p2cread, p2cwrite,\n', '                        c2pread, c2pwrite,\n', '                        errread, errwrite):\n', '        # self._devnull is not always defined.\n', "        devnull_fd = getattr(self, '_devnull', None)\n", '\n', '        with contextlib.ExitStack() as stack:\n', '            if _mswindows:\n', '                if p2cread != -1:\n', '                    stack.callback(p2cread.Close)\n', '                if c2pwrite != -1:\n', '                    stack.callback(c2pwrite.Close)\n', '                if errwrite != -1:\n', '                    stack.callback(errwrite.Close)\n', '            else:\n', '                if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd:\n', '                    stack.callback(os.close, p2cread)\n', '                if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd:\n', '                    stack.callback(os.close, c2pwrite)\n', '                if errwrite != -1 and errread != -1 and errwrite != devnull_fd:\n', '                    stack.callback(os.close, errwrite)\n', '\n', '            if devnull_fd is not None:\n', '                stack.callback(os.close, devnull_fd)\n', '\n', '        # Prevent a double close of these handles/fds from __init__ on error.\n', '        self._closed_child_pipe_fds = True\n', '\n', '    if _mswindows:\n', '        #\n', '        # Windows methods\n', '        #\n', '        def _get_handles(self, stdin, stdout, stderr):\n', '            """Construct and return tuple with IO objects:\n', '            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite\n', '            """\n', '            if stdin is None and stdout is None and stderr is None:\n', '                return (-1, -1, -1, -1, -1, -1)\n', '\n', '            p2cread, p2cwrite = -1, -1\n', '            c2pread, c2pwrite = -1, -1\n', '            errread, errwrite = -1, -1\n', '\n', '            if stdin is None:\n', '                p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)\n', '                if p2cread is None:\n', '                    p2cread, _ = _winapi.CreatePipe(None, 0)\n', '                    p2cread = Handle(p2cread)\n', '                    _winapi.CloseHandle(_)\n', '            elif stdin == PIPE:\n', '                p2cread, p2cwrite = _winapi.CreatePipe(None, 0)\n', '                p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite)\n', '            elif stdin == DEVNULL:\n', '                p2cread = msvcrt.get_osfhandle(self._get_devnull())\n', '            elif isinstance(stdin, int):\n', '                p2cread = msvcrt.get_osfhandle(stdin)\n', '            else:\n', '                # Assuming file-like object\n', '                p2cread = msvcrt.get_osfhandle(stdin.fileno())\n', '            p2cread = self._make_inheritable(p2cread)\n', '\n', '            if stdout is None:\n', '                c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE)\n', '                if c2pwrite is None:\n', '                    _, c2pwrite = _winapi.CreatePipe(None, 0)\n', '                    c2pwrite = Handle(c2pwrite)\n', '                    _winapi.CloseHandle(_)\n', '            elif stdout == PIPE:\n', '                c2pread, c2pwrite = _winapi.CreatePipe(None, 0)\n', '                c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite)\n', '            elif stdout == DEVNULL:\n', '                c2pwrite = msvcrt.get_osfhandle(self._get_devnull())\n', '            elif isinstance(stdout, int):\n', '                c2pwrite = msvcrt.get_osfhandle(stdout)\n', '            else:\n', '                # Assuming file-like object\n', '                c2pwrite = msvcrt.get_osfhandle(stdout.fileno())\n', '            c2pwrite = self._make_inheritable(c2pwrite)\n', '\n', '            if stderr is None:\n', '                errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)\n', '                if errwrite is None:\n', '                    _, errwrite = _winapi.CreatePipe(None, 0)\n', '                    errwrite = Handle(errwrite)\n', '                    _winapi.CloseHandle(_)\n', '            elif stderr == PIPE:\n', '                errread, errwrite = _winapi.CreatePipe(None, 0)\n', '                errread, errwrite = Handle(errread), Handle(errwrite)\n', '            elif stderr == STDOUT:\n', '                errwrite = c2pwrite\n', '            elif stderr == DEVNULL:\n', '                errwrite = msvcrt.get_osfhandle(self._get_devnull())\n', '            elif isinstance(stderr, int):\n', '                errwrite = msvcrt.get_osfhandle(stderr)\n', '            else:\n', '                # Assuming file-like object\n', '                errwrite = msvcrt.get_osfhandle(stderr.fileno())\n', '            errwrite = self._make_inheritable(errwrite)\n', '\n', '            return (p2cread, p2cwrite,\n', '                    c2pread, c2pwrite,\n', '                    errread, errwrite)\n', '\n', '\n', '        def _make_inheritable(self, handle):\n', '            """Return a duplicate of handle, which is inheritable"""\n', '            h = _winapi.DuplicateHandle(\n', '                _winapi.GetCurrentProcess(), handle,\n', '                _winapi.GetCurrentProcess(), 0, 1,\n', '                _winapi.DUPLICATE_SAME_ACCESS)\n', '            return Handle(h)\n', '\n', '\n', '        def _filter_handle_list(self, handle_list):\n', '            """Filter out console handles that can\'t be used\n', '            in lpAttributeList["handle_list"] and make sure the list\n', '            isn\'t empty. This also removes duplicate handles."""\n', "            # An handle with it's lowest two bits set might be a special console\n", '            # handle that if passed in lpAttributeList["handle_list"], will\n', '            # cause it to fail.\n', '            return list({handle for handle in handle_list\n', '                         if handle & 0x3 != 0x3\n', '                         or _winapi.GetFileType(handle) !=\n', '                            _winapi.FILE_TYPE_CHAR})\n', '\n', '\n', '        def _execute_child(self, args, executable, preexec_fn, close_fds,\n', '                           pass_fds, cwd, env,\n', '                           startupinfo, creationflags, shell,\n', '                           p2cread, p2cwrite,\n', '                           c2pread, c2pwrite,\n', '                           errread, errwrite,\n', '                           unused_restore_signals,\n', '                           unused_gid, unused_gids, unused_uid,\n', '                           unused_umask,\n', '                           unused_start_new_session):\n', '            """Execute program (MS Windows version)"""\n', '\n', '            assert not pass_fds, "pass_fds not supported on Windows."\n', '\n', '            if isinstance(args, str):\n', '                pass\n', '            elif isinstance(args, bytes):\n', '                if shell:\n', "                    raise TypeError('bytes args is not allowed on Windows')\n", '                args = list2cmdline([args])\n', '            elif isinstance(args, os.PathLike):\n', '                if shell:\n', "                    raise TypeError('path-like args is not allowed when '\n", "                                    'shell is true')\n", '                args = list2cmdline([args])\n', '            else:\n', '                args = list2cmdline(args)\n', '\n', '            if executable is not None:\n', '                executable = os.fsdecode(executable)\n', '\n', '            # Process startup details\n', '            if startupinfo is None:\n', '                startupinfo = STARTUPINFO()\n', '            else:\n', '                # bpo-34044: Copy STARTUPINFO since it is modified above,\n', '                # so the caller can reuse it multiple times.\n', '                startupinfo = startupinfo.copy()\n', '\n', '            use_std_handles = -1 not in (p2cread, c2pwrite, errwrite)\n', '            if use_std_handles:\n', '                startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES\n', '                startupinfo.hStdInput = p2cread\n', '                startupinfo.hStdOutput = c2pwrite\n', '                startupinfo.hStdError = errwrite\n', '\n', '            attribute_list = startupinfo.lpAttributeList\n', '            have_handle_list = bool(attribute_list and\n', '                                    "handle_list" in attribute_list and\n', '                                    attribute_list["handle_list"])\n', '\n', '            # If we were given an handle_list or need to create one\n', '            if have_handle_list or (use_std_handles and close_fds):\n', '                if attribute_list is None:\n', '                    attribute_list = startupinfo.lpAttributeList = {}\n', '                handle_list = attribute_list["handle_list"] = \\\n', '                    list(attribute_list.get("handle_list", []))\n', '\n', '                if use_std_handles:\n', '                    handle_list += [int(p2cread), int(c2pwrite), int(errwrite)]\n', '\n', '                handle_list[:] = self._filter_handle_list(handle_list)\n', '\n', '                if handle_list:\n', '                    if not close_fds:\n', '                        warnings.warn("startupinfo.lpAttributeList[\'handle_list\'] "\n', '                                      "overriding close_fds", RuntimeWarning)\n', '\n', '                    # When using the handle_list we always request to inherit\n', '                    # handles but the only handles that will be inherited are\n', '                    # the ones in the handle_list\n', '                    close_fds = False\n', '\n', '            if shell:\n', '                startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW\n', '                startupinfo.wShowWindow = _winapi.SW_HIDE\n', '                comspec = os.environ.get("COMSPEC", "cmd.exe")\n', '                args = \'{} /c "{}"\'.format (comspec, args)\n', '\n', '            if cwd is not None:\n', '                cwd = os.fsdecode(cwd)\n', '\n', '            sys.audit("subprocess.Popen", executable, args, cwd, env)\n', '\n', '            # Start the process\n', '            try:\n', '                hp, ht, pid, tid = _winapi.CreateProcess(executable, args,\n', '                                         # no special security\n', '                                         None, None,\n', '                                         int(not close_fds),\n', '                                         creationflags,\n', '                                         env,\n', '                                         cwd,\n', '                                         startupinfo)\n', '            finally:\n', "                # Child is launched. Close the parent's copy of those pipe\n", '                # handles that only the child should have open.  You need\n', '                # to make sure that no handles to the write end of the\n', '                # output pipe are maintained in this process or else the\n', '                # pipe will not close when the child process exits and the\n', '                # ReadFile will hang.\n', '                self._close_pipe_fds(p2cread, p2cwrite,\n', '                                     c2pread, c2pwrite,\n', '                                     errread, errwrite)\n', '\n', '            # Retain the process handle, but close the thread handle\n', '            self._child_created = True\n', '            self._handle = Handle(hp)\n', '            self.pid = pid\n', '            _winapi.CloseHandle(ht)\n', '\n', '        def _internal_poll(self, _deadstate=None,\n', '                _WaitForSingleObject=_winapi.WaitForSingleObject,\n', '                _WAIT_OBJECT_0=_winapi.WAIT_OBJECT_0,\n', '                _GetExitCodeProcess=_winapi.GetExitCodeProcess):\n', '            """Check if child process has terminated.  Returns returncode\n', '            attribute.\n', '\n', '            This method is called by __del__, so it can only refer to objects\n', '            in its local scope.\n', '\n', '            """\n', '            if self.returncode is None:\n', '                if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:\n', '                    self.returncode = _GetExitCodeProcess(self._handle)\n', '            return self.returncode\n', '\n', '\n', '        def _wait(self, timeout):\n', '            """Internal implementation of wait() on Windows."""\n', '            if timeout is None:\n', '                timeout_millis = _winapi.INFINITE\n', '            else:\n', '                timeout_millis = int(timeout * 1000)\n', '            if self.returncode is None:\n', '                # API note: Returns immediately if timeout_millis == 0.\n', '                result = _winapi.WaitForSingleObject(self._handle,\n', '                                                     timeout_millis)\n', '                if result == _winapi.WAIT_TIMEOUT:\n', '                    raise TimeoutExpired(self.args, timeout)\n', '                self.returncode = _winapi.GetExitCodeProcess(self._handle)\n', '            return self.returncode\n', '\n', '\n', '        def _readerthread(self, fh, buffer):\n', '            buffer.append(fh.read())\n', '            fh.close()\n', '\n', '\n', '        def _communicate(self, input, endtime, orig_timeout):\n', '            # Start reader threads feeding into a list hanging off of this\n', "            # object, unless they've already been started.\n", '            if self.stdout and not hasattr(self, "_stdout_buff"):\n', '                self._stdout_buff = []\n', '                self.stdout_thread = \\\n', '                        threading.Thread(target=self._readerthread,\n', '                                         args=(self.stdout, self._stdout_buff))\n', '                self.stdout_thread.daemon = True\n', '                self.stdout_thread.start()\n', '            if self.stderr and not hasattr(self, "_stderr_buff"):\n', '                self._stderr_buff = []\n', '                self.stderr_thread = \\\n', '                        threading.Thread(target=self._readerthread,\n', '                                         args=(self.stderr, self._stderr_buff))\n', '                self.stderr_thread.daemon = True\n', '                self.stderr_thread.start()\n', '\n', '            if self.stdin:\n', '                self._stdin_write(input)\n', '\n', '            # Wait for the reader threads, or time out.  If we time out, the\n', '            # threads remain reading and the fds left open in case the user\n', '            # calls communicate again.\n', '            if self.stdout is not None:\n', '                self.stdout_thread.join(self._remaining_time(endtime))\n', '                if self.stdout_thread.is_alive():\n', '                    raise TimeoutExpired(self.args, orig_timeout)\n', '            if self.stderr is not None:\n', '                self.stderr_thread.join(self._remaining_time(endtime))\n', '                if self.stderr_thread.is_alive():\n', '                    raise TimeoutExpired(self.args, orig_timeout)\n', '\n', '            # Collect the output from and close both pipes, now that we know\n', '            # both have been read successfully.\n', '            stdout = None\n', '            stderr = None\n', '            if self.stdout:\n', '                stdout = self._stdout_buff\n', '                self.stdout.close()\n', '            if self.stderr:\n', '                stderr = self._stderr_buff\n', '                self.stderr.close()\n', '\n', '            # All data exchanged.  Translate lists into strings.\n', '            stdout = stdout[0] if stdout else None\n', '            stderr = stderr[0] if stderr else None\n', '\n', '            return (stdout, stderr)\n', '\n', '        def send_signal(self, sig):\n', '            """Send a signal to the process."""\n', "            # Don't signal a process that we know has already died.\n", '            if self.returncode is not None:\n', '                return\n', '            if sig == signal.SIGTERM:\n', '                self.terminate()\n', '            elif sig == signal.CTRL_C_EVENT:\n', '                os.kill(self.pid, signal.CTRL_C_EVENT)\n', '            elif sig == signal.CTRL_BREAK_EVENT:\n', '                os.kill(self.pid, signal.CTRL_BREAK_EVENT)\n', '            else:\n', '                raise ValueError("Unsupported signal: {}".format(sig))\n', '\n', '        def terminate(self):\n', '            """Terminates the process."""\n', "            # Don't terminate a process that we know has already died.\n", '            if self.returncode is not None:\n', '                return\n', '            try:\n', '                _winapi.TerminateProcess(self._handle, 1)\n', '            except PermissionError:\n', '                # ERROR_ACCESS_DENIED (winerror 5) is received when the\n', '                # process already died.\n', '                rc = _winapi.GetExitCodeProcess(self._handle)\n', '                if rc == _winapi.STILL_ACTIVE:\n', '                    raise\n', '                self.returncode = rc\n', '\n', '        kill = terminate\n', '\n', '    else:\n', '        #\n', '        # POSIX methods\n', '        #\n', '        def _get_handles(self, stdin, stdout, stderr):\n', '            """Construct and return tuple with IO objects:\n', '            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite\n', '            """\n', '            p2cread, p2cwrite = -1, -1\n', '            c2pread, c2pwrite = -1, -1\n', '            errread, errwrite = -1, -1\n', '\n', '            if stdin is None:\n', '                pass\n', '            elif stdin == PIPE:\n', '                p2cread, p2cwrite = os.pipe()\n', '                if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"):\n', '                    fcntl.fcntl(p2cwrite, fcntl.F_SETPIPE_SZ, self.pipesize)\n', '            elif stdin == DEVNULL:\n', '                p2cread = self._get_devnull()\n', '            elif isinstance(stdin, int):\n', '                p2cread = stdin\n', '            else:\n', '                # Assuming file-like object\n', '                p2cread = stdin.fileno()\n', '\n', '            if stdout is None:\n', '                pass\n', '            elif stdout == PIPE:\n', '                c2pread, c2pwrite = os.pipe()\n', '                if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"):\n', '                    fcntl.fcntl(c2pwrite, fcntl.F_SETPIPE_SZ, self.pipesize)\n', '            elif stdout == DEVNULL:\n', '                c2pwrite = self._get_devnull()\n', '            elif isinstance(stdout, int):\n', '                c2pwrite = stdout\n', '            else:\n', '                # Assuming file-like object\n', '                c2pwrite = stdout.fileno()\n', '\n', '            if stderr is None:\n', '                pass\n', '            elif stderr == PIPE:\n', '                errread, errwrite = os.pipe()\n', '                if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"):\n', '                    fcntl.fcntl(errwrite, fcntl.F_SETPIPE_SZ, self.pipesize)\n', '            elif stderr == STDOUT:\n', '                if c2pwrite != -1:\n', '                    errwrite = c2pwrite\n', "                else: # child's stdout is not set, use parent's stdout\n", '                    errwrite = sys.__stdout__.fileno()\n', '            elif stderr == DEVNULL:\n', '                errwrite = self._get_devnull()\n', '            elif isinstance(stderr, int):\n', '                errwrite = stderr\n', '            else:\n', '                # Assuming file-like object\n', '                errwrite = stderr.fileno()\n', '\n', '            return (p2cread, p2cwrite,\n', '                    c2pread, c2pwrite,\n', '                    errread, errwrite)\n', '\n', '\n', '        def _posix_spawn(self, args, executable, env, restore_signals,\n', '                         p2cread, p2cwrite,\n', '                         c2pread, c2pwrite,\n', '                         errread, errwrite):\n', '            """Execute program using os.posix_spawn()."""\n', '            if env is None:\n', '                env = os.environ\n', '\n', '            kwargs = {}\n', '            if restore_signals:\n', '                # See _Py_RestoreSignals() in Python/pylifecycle.c\n', '                sigset = []\n', "                for signame in ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ'):\n", '                    signum = getattr(signal, signame, None)\n', '                    if signum is not None:\n', '                        sigset.append(signum)\n', "                kwargs['setsigdef'] = sigset\n", '\n', '            file_actions = []\n', '            for fd in (p2cwrite, c2pread, errread):\n', '                if fd != -1:\n', '                    file_actions.append((os.POSIX_SPAWN_CLOSE, fd))\n', '            for fd, fd2 in (\n', '                (p2cread, 0),\n', '                (c2pwrite, 1),\n', '                (errwrite, 2),\n', '            ):\n', '                if fd != -1:\n', '                    file_actions.append((os.POSIX_SPAWN_DUP2, fd, fd2))\n', '            if file_actions:\n', "                kwargs['file_actions'] = file_actions\n", '\n', '            self.pid = os.posix_spawn(executable, args, env, **kwargs)\n', '            self._child_created = True\n', '\n', '            self._close_pipe_fds(p2cread, p2cwrite,\n', '                                 c2pread, c2pwrite,\n', '                                 errread, errwrite)\n', '\n', '        def _execute_child(self, args, executable, preexec_fn, close_fds,\n', '                           pass_fds, cwd, env,\n', '                           startupinfo, creationflags, shell,\n', '                           p2cread, p2cwrite,\n', '                           c2pread, c2pwrite,\n', '                           errread, errwrite,\n', '                           restore_signals,\n', '                           gid, gids, uid, umask,\n', '                           start_new_session):\n', '            """Execute program (POSIX version)"""\n', '\n', '            if isinstance(args, (str, bytes)):\n', '                args = [args]\n', '            elif isinstance(args, os.PathLike):\n', '                if shell:\n', "                    raise TypeError('path-like args is not allowed when '\n", "                                    'shell is true')\n", '                args = [args]\n', '            else:\n', '                args = list(args)\n', '\n', '            if shell:\n', "                # On Android the default shell is at '/system/bin/sh'.\n", "                unix_shell = ('/system/bin/sh' if\n", "                          hasattr(sys, 'getandroidapilevel') else '/nix/store/dsd5gz46hdbdk2rfdimqddhq6m8m8fqs-bash-5.1-p16/bin/sh')\n", '                args = [unix_shell, "-c"] + args\n', '                if executable:\n', '                    args[0] = executable\n', '\n', '            if executable is None:\n', '                executable = args[0]\n', '\n', '            sys.audit("subprocess.Popen", executable, args, cwd, env)\n', '\n', '            if (_USE_POSIX_SPAWN\n', '                    and os.path.dirname(executable)\n', '                    and preexec_fn is None\n', '                    and not close_fds\n', '                    and not pass_fds\n', '                    and cwd is None\n', '                    and (p2cread == -1 or p2cread > 2)\n', '                    and (c2pwrite == -1 or c2pwrite > 2)\n', '                    and (errwrite == -1 or errwrite > 2)\n', '                    and not start_new_session\n', '                    and gid is None\n', '                    and gids is None\n', '                    and uid is None\n', '                    and umask < 0):\n', '                self._posix_spawn(args, executable, env, restore_signals,\n', '                                  p2cread, p2cwrite,\n', '                                  c2pread, c2pwrite,\n', '                                  errread, errwrite)\n', '                return\n', '\n', '            orig_executable = executable\n', '\n', '            # For transferring possible exec failure from child to parent.\n', '            # Data format: "exception name:hex errno:description"\n', '            # Pickle is not used; it is complex and involves memory allocation.\n', '            errpipe_read, errpipe_write = os.pipe()\n', '            # errpipe_write must not be in the standard io 0, 1, or 2 fd range.\n', '            low_fds_to_close = []\n', '            while errpipe_write < 3:\n', '                low_fds_to_close.append(errpipe_write)\n', '                errpipe_write = os.dup(errpipe_write)\n', '            for low_fd in low_fds_to_close:\n', '                os.close(low_fd)\n', '            try:\n', '                try:\n', '                    # We must avoid complex work that could involve\n', '                    # malloc or free in the child process to avoid\n', '                    # potential deadlocks, thus we do all this here.\n', '                    # and pass it to fork_exec()\n', '\n', '                    if env is not None:\n', '                        env_list = []\n', '                        for k, v in env.items():\n', '                            k = os.fsencode(k)\n', "                            if b'=' in k:\n", '                                raise ValueError("illegal environment variable name")\n', "                            env_list.append(k + b'=' + os.fsencode(v))\n", '                    else:\n', '                        env_list = None  # Use execv instead of execve.\n', '                    executable = os.fsencode(executable)\n', '                    if os.path.dirname(executable):\n', '                        executable_list = (executable,)\n', '                    else:\n', '                        # This matches the behavior of os._execvpe().\n', '                        executable_list = tuple(\n', '                            os.path.join(os.fsencode(dir), executable)\n', '                            for dir in os.get_exec_path(env))\n', '                    fds_to_keep = set(pass_fds)\n', '                    fds_to_keep.add(errpipe_write)\n', '                    self.pid = _posixsubprocess.fork_exec(\n', '                            args, executable_list,\n', '                            close_fds, tuple(sorted(map(int, fds_to_keep))),\n', '                            cwd, env_list,\n', '                            p2cread, p2cwrite, c2pread, c2pwrite,\n', '                            errread, errwrite,\n', '                            errpipe_read, errpipe_write,\n', '                            restore_signals, start_new_session,\n', '                            gid, gids, uid, umask,\n', '                            preexec_fn)\n', '                    self._child_created = True\n', '                finally:\n', '                    # be sure the FD is closed no matter what\n', '                    os.close(errpipe_write)\n', '\n', '                self._close_pipe_fds(p2cread, p2cwrite,\n', '                                     c2pread, c2pwrite,\n', '                                     errread, errwrite)\n', '\n', '                # Wait for exec to fail or succeed; possibly raising an\n', '                # exception (limited in size)\n', '                errpipe_data = bytearray()\n', '                while True:\n', '                    part = os.read(errpipe_read, 50000)\n', '                    errpipe_data += part\n', '                    if not part or len(errpipe_data) > 50000:\n', '                        break\n', '            finally:\n', '                # be sure the FD is closed no matter what\n', '                os.close(errpipe_read)\n', '\n', '            if errpipe_data:\n', '                try:\n', '                    pid, sts = os.waitpid(self.pid, 0)\n', '                    if pid == self.pid:\n', '                        self._handle_exitstatus(sts)\n', '                    else:\n', '                        self.returncode = sys.maxsize\n', '                except ChildProcessError:\n', '                    pass\n', '\n', '                try:\n', '                    exception_name, hex_errno, err_msg = (\n', "                            errpipe_data.split(b':', 2))\n", '                    # The encoding here should match the encoding\n', '                    # written in by the subprocess implementations\n', '                    # like _posixsubprocess\n', '                    err_msg = err_msg.decode()\n', '                except ValueError:\n', "                    exception_name = b'SubprocessError'\n", "                    hex_errno = b'0'\n", "                    err_msg = 'Bad exception data from child: {!r}'.format(\n", '                                  bytes(errpipe_data))\n', '                child_exception_type = getattr(\n', "                        builtins, exception_name.decode('ascii'),\n", '                        SubprocessError)\n', '                if issubclass(child_exception_type, OSError) and hex_errno:\n', '                    errno_num = int(hex_errno, 16)\n', '                    child_exec_never_called = (err_msg == "noexec")\n', '                    if child_exec_never_called:\n', '                        err_msg = ""\n', '                        # The error must be from chdir(cwd).\n', '                        err_filename = cwd\n', '                    else:\n', '                        err_filename = orig_executable\n', '                    if errno_num != 0:\n', '                        err_msg = os.strerror(errno_num)\n', '                    raise child_exception_type(errno_num, err_msg, err_filename)\n', '                raise child_exception_type(err_msg)\n', '\n', '\n', '        def _handle_exitstatus(self, sts,\n', '                               waitstatus_to_exitcode=os.waitstatus_to_exitcode,\n', '                               _WIFSTOPPED=os.WIFSTOPPED,\n', '                               _WSTOPSIG=os.WSTOPSIG):\n', '            """All callers to this function MUST hold self._waitpid_lock."""\n', '            # This method is called (indirectly) by __del__, so it cannot\n', '            # refer to anything outside of its local scope.\n', '            if _WIFSTOPPED(sts):\n', '                self.returncode = -_WSTOPSIG(sts)\n', '            else:\n', '                self.returncode = waitstatus_to_exitcode(sts)\n', '\n', '        def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,\n', '                _WNOHANG=os.WNOHANG, _ECHILD=errno.ECHILD):\n', '            """Check if child process has terminated.  Returns returncode\n', '            attribute.\n', '\n', '            This method is called by __del__, so it cannot reference anything\n', '            outside of the local scope (nor can any methods it calls).\n', '\n', '            """\n', '            if self.returncode is None:\n', '                if not self._waitpid_lock.acquire(False):\n', "                    # Something else is busy calling waitpid.  Don't allow two\n", '                    # at once.  We know nothing yet.\n', '                    return None\n', '                try:\n', '                    if self.returncode is not None:\n', '                        return self.returncode  # Another thread waited.\n', '                    pid, sts = _waitpid(self.pid, _WNOHANG)\n', '                    if pid == self.pid:\n', '                        self._handle_exitstatus(sts)\n', '                except OSError as e:\n', '                    if _deadstate is not None:\n', '                        self.returncode = _deadstate\n', '                    elif e.errno == _ECHILD:\n', '                        # This happens if SIGCLD is set to be ignored or\n', '                        # waiting for child processes has otherwise been\n', '                        # disabled for our process.  This child is dead, we\n', "                        # can't get the status.\n", '                        # http://bugs.python.org/issue15756\n', '                        self.returncode = 0\n', '                finally:\n', '                    self._waitpid_lock.release()\n', '            return self.returncode\n', '\n', '\n', '        def _try_wait(self, wait_flags):\n', '            """All callers to this function MUST hold self._waitpid_lock."""\n', '            try:\n', '                (pid, sts) = os.waitpid(self.pid, wait_flags)\n', '            except ChildProcessError:\n', '                # This happens if SIGCLD is set to be ignored or waiting\n', '                # for child processes has otherwise been disabled for our\n', "                # process.  This child is dead, we can't get the status.\n", '                pid = self.pid\n', '                sts = 0\n', '            return (pid, sts)\n', '\n', '\n', '        def _wait(self, timeout):\n', '            """Internal implementation of wait() on POSIX."""\n', '            if self.returncode is not None:\n', '                return self.returncode\n', '\n', '            if timeout is not None:\n', '                endtime = _time() + timeout\n', '                # Enter a busy loop if we have a timeout.  This busy loop was\n', '                # cribbed from Lib/threading.py in Thread.wait() at r71065.\n', '                delay = 0.0005 # 500 us -> initial delay of 1 ms\n', '                while True:\n', '                    if self._waitpid_lock.acquire(False):\n', '                        try:\n', '                            if self.returncode is not None:\n', '                                break  # Another thread waited.\n', '                            (pid, sts) = self._try_wait(os.WNOHANG)\n', '                            assert pid == self.pid or pid == 0\n', '                            if pid == self.pid:\n', '                                self._handle_exitstatus(sts)\n', '                                break\n', '                        finally:\n', '                            self._waitpid_lock.release()\n', '                    remaining = self._remaining_time(endtime)\n', '                    if remaining <= 0:\n', '                        raise TimeoutExpired(self.args, timeout)\n', '                    delay = min(delay * 2, remaining, .05)\n', '                    time.sleep(delay)\n', '            else:\n', '                while self.returncode is None:\n', '                    with self._waitpid_lock:\n', '                        if self.returncode is not None:\n', '                            break  # Another thread waited.\n', '                        (pid, sts) = self._try_wait(0)\n', '                        # Check the pid and loop as waitpid has been known to\n', '                        # return 0 even without WNOHANG in odd situations.\n', '                        # http://bugs.python.org/issue14396.\n', '                        if pid == self.pid:\n', '                            self._handle_exitstatus(sts)\n', '            return self.returncode\n', '\n', '\n', '        def _communicate(self, input, endtime, orig_timeout):\n', '            if self.stdin and not self._communication_started:\n', '                # Flush stdio buffer.  This might block, if the user has\n', '                # been writing to .stdin in an uncontrolled fashion.\n', '                try:\n', '                    self.stdin.flush()\n', '                except BrokenPipeError:\n', '                    pass  # communicate() must ignore BrokenPipeError.\n', '                if not input:\n', '                    try:\n', '                        self.stdin.close()\n', '                    except BrokenPipeError:\n', '                        pass  # communicate() must ignore BrokenPipeError.\n', '\n', '            stdout = None\n', '            stderr = None\n', '\n', "            # Only create this mapping if we haven't already.\n", '            if not self._communication_started:\n', '                self._fileobj2output = {}\n', '                if self.stdout:\n', '                    self._fileobj2output[self.stdout] = []\n', '                if self.stderr:\n', '                    self._fileobj2output[self.stderr] = []\n', '\n', '            if self.stdout:\n', '                stdout = self._fileobj2output[self.stdout]\n', '            if self.stderr:\n', '                stderr = self._fileobj2output[self.stderr]\n', '\n', '            self._save_input(input)\n', '\n', '            if self._input:\n', '                input_view = memoryview(self._input)\n', '\n', '            with _PopenSelector() as selector:\n', '                if self.stdin and input:\n', '                    selector.register(self.stdin, selectors.EVENT_WRITE)\n', '                if self.stdout and not self.stdout.closed:\n', '                    selector.register(self.stdout, selectors.EVENT_READ)\n', '                if self.stderr and not self.stderr.closed:\n', '                    selector.register(self.stderr, selectors.EVENT_READ)\n', '\n', '                while selector.get_map():\n', '                    timeout = self._remaining_time(endtime)\n', '                    if timeout is not None and timeout < 0:\n', '                        self._check_timeout(endtime, orig_timeout,\n', '                                            stdout, stderr,\n', '                                            skip_check_and_raise=True)\n', '                        raise RuntimeError(  # Impossible :)\n', "                            '_check_timeout(..., skip_check_and_raise=True) '\n", "                            'failed to raise TimeoutExpired.')\n", '\n', '                    ready = selector.select(timeout)\n', '                    self._check_timeout(endtime, orig_timeout, stdout, stderr)\n', '\n', '                    # XXX Rewrite these to use non-blocking I/O on the file\n', '                    # objects; they are no longer using C stdio!\n', '\n', '                    for key, events in ready:\n', '                        if key.fileobj is self.stdin:\n', '                            chunk = input_view[self._input_offset :\n', '                                               self._input_offset + _PIPE_BUF]\n', '                            try:\n', '                                self._input_offset += os.write(key.fd, chunk)\n', '                            except BrokenPipeError:\n', '                                selector.unregister(key.fileobj)\n', '                                key.fileobj.close()\n', '                            else:\n', '                                if self._input_offset >= len(self._input):\n', '                                    selector.unregister(key.fileobj)\n', '                                    key.fileobj.close()\n', '                        elif key.fileobj in (self.stdout, self.stderr):\n', '                            data = os.read(key.fd, 32768)\n', '                            if not data:\n', '                                selector.unregister(key.fileobj)\n', '                                key.fileobj.close()\n', '                            self._fileobj2output[key.fileobj].append(data)\n', '\n', '            self.wait(timeout=self._remaining_time(endtime))\n', '\n', '            # All data exchanged.  Translate lists into strings.\n', '            if stdout is not None:\n', "                stdout = b''.join(stdout)\n", '            if stderr is not None:\n', "                stderr = b''.join(stderr)\n", '\n', '            # Translate newlines, if requested.\n', '            # This also turns bytes into strings.\n', '            if self.text_mode:\n', '                if stdout is not None:\n', '                    stdout = self._translate_newlines(stdout,\n', '                                                      self.stdout.encoding,\n', '                                                      self.stdout.errors)\n', '                if stderr is not None:\n', '                    stderr = self._translate_newlines(stderr,\n', '                                                      self.stderr.encoding,\n', '                                                      self.stderr.errors)\n', '\n', '            return (stdout, stderr)\n', '\n', '\n', '        def _save_input(self, input):\n', '            # This method is called from the _communicate_with_*() methods\n', '            # so that if we time out while communicating, we can continue\n', '            # sending input if we retry.\n', '            if self.stdin and self._input is None:\n', '                self._input_offset = 0\n', '                self._input = input\n', '                if input is not None and self.text_mode:\n', '                    self._input = self._input.encode(self.stdin.encoding,\n', '                                                     self.stdin.errors)\n', '\n', '\n', '        def send_signal(self, sig):\n', '            """Send a signal to the process."""\n', '            # bpo-38630: Polling reduces the risk of sending a signal to the\n', '            # wrong process if the process completed, the Popen.returncode\n', '            # attribute is still None, and the pid has been reassigned\n', '            # (recycled) to a new different process. This race condition can\n', '            # happens in two cases.\n', '            #\n', '            # Case 1. Thread A calls Popen.poll(), thread B calls\n', '            # Popen.send_signal(). In thread A, waitpid() succeed and returns\n', '            # the exit status. Thread B calls kill() because poll() in thread A\n', '            # did not set returncode yet. Calling poll() in thread B prevents\n', '            # the race condition thanks to Popen._waitpid_lock.\n', '            #\n', '            # Case 2. waitpid(pid, 0) has been called directly, without\n', '            # using Popen methods: returncode is still None is this case.\n', '            # Calling Popen.poll() will set returncode to a default value,\n', '            # since waitpid() fails with ProcessLookupError.\n', '            self.poll()\n', '            if self.returncode is not None:\n', '                # Skip signalling a process that we know has already died.\n', '                return\n', '\n', '            # The race condition can still happen if the race condition\n', '            # described above happens between the returncode test\n', '            # and the kill() call.\n', '            try:\n', '                os.kill(self.pid, sig)\n', '            except ProcessLookupError:\n', '                # Supress the race condition error; bpo-40550.\n', '                pass\n', '\n', '        def terminate(self):\n', '            """Terminate the process with SIGTERM\n', '            """\n', '            self.send_signal(signal.SIGTERM)\n', '\n', '        def kill(self):\n', '            """Kill the process with SIGKILL\n', '            """\n', '            self.send_signal(signal.SIGKILL)\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/subprocess.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/inspect.py': (123886, 1.0, ['"""Get useful information from live Python objects.\n', '\n', 'This module encapsulates the interface provided by the internal special\n', 'attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.\n', 'It also provides some help for examining source code and class layout.\n', '\n', 'Here are some of the useful functions provided by this module:\n', '\n', '    ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),\n', '        isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),\n', '        isroutine() - check object types\n', '    getmembers() - get members of an object that satisfy a given condition\n', '\n', "    getfile(), getsourcefile(), getsource() - find an object's source code\n", '    getdoc(), getcomments() - get documentation on an object\n', '    getmodule() - determine the module that an object came from\n', '    getclasstree() - arrange classes so as to represent their hierarchy\n', '\n', '    getargvalues(), getcallargs() - get info about function arguments\n', '    getfullargspec() - same, with support for Python 3 features\n', '    formatargvalues() - format an argument spec\n', '    getouterframes(), getinnerframes() - get info about frames\n', '    currentframe() - get the current stack frame\n', '    stack(), trace() - get info about frames on the stack or in a traceback\n', '\n', '    signature() - get a Signature object for the callable\n', '\n', "    get_annotations() - safely compute an object's annotations\n", '"""\n', '\n', '# This module is in the public domain.  No warranties.\n', '\n', "__author__ = ('Ka-Ping Yee <ping@lfw.org>',\n", "              'Yury Selivanov <yselivanov@sprymix.com>')\n", '\n', 'import abc\n', 'import ast\n', 'import dis\n', 'import collections.abc\n', 'import enum\n', 'import importlib.machinery\n', 'import itertools\n', 'import linecache\n', 'import os\n', 'import re\n', 'import sys\n', 'import tokenize\n', 'import token\n', 'import types\n', 'import warnings\n', 'import functools\n', 'import builtins\n', 'from operator import attrgetter\n', 'from collections import namedtuple, OrderedDict\n', '\n', '# Create constants for the compiler flags in Include/code.h\n', '# We try to get them from dis to avoid duplication\n', 'mod_dict = globals()\n', 'for k, v in dis.COMPILER_FLAG_NAMES.items():\n', '    mod_dict["CO_" + v] = k\n', '\n', '# See Include/object.h\n', 'TPFLAGS_IS_ABSTRACT = 1 << 20\n', '\n', '\n', 'def get_annotations(obj, *, globals=None, locals=None, eval_str=False):\n', '    """Compute the annotations dict for an object.\n', '\n', '    obj may be a callable, class, or module.\n', '    Passing in an object of any other type raises TypeError.\n', '\n', '    Returns a dict.  get_annotations() returns a new dict every time\n', "    it's called; calling it twice on the same object will return two\n", '    different but equivalent dicts.\n', '\n', '    This function handles several details for you:\n', '\n', '      * If eval_str is true, values of type str will\n', '        be un-stringized using eval().  This is intended\n', '        for use with stringized annotations\n', '        ("from __future__ import annotations").\n', "      * If obj doesn't have an annotations dict, returns an\n", '        empty dict.  (Functions and methods always have an\n', '        annotations dict; classes, modules, and other types of\n', '        callables may not.)\n', '      * Ignores inherited annotations on classes.  If a class\n', "        doesn't have its own annotations dict, returns an empty dict.\n", '      * All accesses to object members and dict values are done\n', '        using getattr() and dict.get() for safety.\n', '      * Always, always, always returns a freshly-created dict.\n', '\n', '    eval_str controls whether or not values of type str are replaced\n', '    with the result of calling eval() on those values:\n', '\n', '      * If eval_str is true, eval() is called on values of type str.\n', '      * If eval_str is false (the default), values of type str are unchanged.\n', '\n', '    globals and locals are passed in to eval(); see the documentation\n', '    for eval() for more information.  If either globals or locals is\n', '    None, this function may replace that value with a context-specific\n', '    default, contingent on type(obj):\n', '\n', '      * If obj is a module, globals defaults to obj.__dict__.\n', '      * If obj is a class, globals defaults to\n', '        sys.modules[obj.__module__].__dict__ and locals\n', '        defaults to the obj class namespace.\n', '      * If obj is a callable, globals defaults to obj.__globals__,\n', '        although if obj is a wrapped function (using\n', '        functools.update_wrapper()) it is first unwrapped.\n', '    """\n', '    if isinstance(obj, type):\n', '        # class\n', "        obj_dict = getattr(obj, '__dict__', None)\n", "        if obj_dict and hasattr(obj_dict, 'get'):\n", "            ann = obj_dict.get('__annotations__', None)\n", '            if isinstance(ann, types.GetSetDescriptorType):\n', '                ann = None\n', '        else:\n', '            ann = None\n', '\n', '        obj_globals = None\n', "        module_name = getattr(obj, '__module__', None)\n", '        if module_name:\n', '            module = sys.modules.get(module_name, None)\n', '            if module:\n', "                obj_globals = getattr(module, '__dict__', None)\n", '        obj_locals = dict(vars(obj))\n', '        unwrap = obj\n', '    elif isinstance(obj, types.ModuleType):\n', '        # module\n', "        ann = getattr(obj, '__annotations__', None)\n", "        obj_globals = getattr(obj, '__dict__')\n", '        obj_locals = None\n', '        unwrap = None\n', '    elif callable(obj):\n', '        # this includes types.Function, types.BuiltinFunctionType,\n', '        # types.BuiltinMethodType, functools.partial, functools.singledispatch,\n', '        # "class funclike" from Lib/test/test_inspect... on and on it goes.\n', "        ann = getattr(obj, '__annotations__', None)\n", "        obj_globals = getattr(obj, '__globals__', None)\n", '        obj_locals = None\n', '        unwrap = obj\n', '    else:\n', '        raise TypeError(f"{obj!r} is not a module, class, or callable.")\n', '\n', '    if ann is None:\n', '        return {}\n', '\n', '    if not isinstance(ann, dict):\n', '        raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")\n', '\n', '    if not ann:\n', '        return {}\n', '\n', '    if not eval_str:\n', '        return dict(ann)\n', '\n', '    if unwrap is not None:\n', '        while True:\n', "            if hasattr(unwrap, '__wrapped__'):\n", '                unwrap = unwrap.__wrapped__\n', '                continue\n', '            if isinstance(unwrap, functools.partial):\n', '                unwrap = unwrap.func\n', '                continue\n', '            break\n', '        if hasattr(unwrap, "__globals__"):\n', '            obj_globals = unwrap.__globals__\n', '\n', '    if globals is None:\n', '        globals = obj_globals\n', '    if locals is None:\n', '        locals = obj_locals\n', '\n', '    return_value = {key:\n', '        value if not isinstance(value, str) else eval(value, globals, locals)\n', '        for key, value in ann.items() }\n', '    return return_value\n', '\n', '\n', '# ----------------------------------------------------------- type-checking\n', 'def ismodule(object):\n', '    """Return true if the object is a module.\n', '\n', '    Module objects provide these attributes:\n', '        __cached__      pathname to byte compiled file\n', '        __doc__         documentation string\n', '        __file__        filename (missing for built-in modules)"""\n', '    return isinstance(object, types.ModuleType)\n', '\n', 'def isclass(object):\n', '    """Return true if the object is a class.\n', '\n', '    Class objects provide these attributes:\n', '        __doc__         documentation string\n', '        __module__      name of module in which this class was defined"""\n', '    return isinstance(object, type)\n', '\n', 'def ismethod(object):\n', '    """Return true if the object is an instance method.\n', '\n', '    Instance method objects provide these attributes:\n', '        __doc__         documentation string\n', '        __name__        name with which this method was defined\n', '        __func__        function object containing implementation of method\n', '        __self__        instance to which this method is bound"""\n', '    return isinstance(object, types.MethodType)\n', '\n', 'def ismethoddescriptor(object):\n', '    """Return true if the object is a method descriptor.\n', '\n', '    But not if ismethod() or isclass() or isfunction() are true.\n', '\n', '    This is new in Python 2.2, and, for example, is true of int.__add__.\n', '    An object passing this test has a __get__ attribute but not a __set__\n', '    attribute, but beyond that the set of attributes varies.  __name__ is\n', '    usually sensible, and __doc__ often is.\n', '\n', '    Methods implemented via descriptors that also pass one of the other\n', '    tests return false from the ismethoddescriptor() test, simply because\n', '    the other tests promise more -- you can, e.g., count on having the\n', '    __func__ attribute (etc) when an object passes ismethod()."""\n', '    if isclass(object) or ismethod(object) or isfunction(object):\n', '        # mutual exclusion\n', '        return False\n', '    tp = type(object)\n', '    return hasattr(tp, "__get__") and not hasattr(tp, "__set__")\n', '\n', 'def isdatadescriptor(object):\n', '    """Return true if the object is a data descriptor.\n', '\n', '    Data descriptors have a __set__ or a __delete__ attribute.  Examples are\n', '    properties (defined in Python) and getsets and members (defined in C).\n', '    Typically, data descriptors will also have __name__ and __doc__ attributes\n', '    (properties, getsets, and members have both of these attributes), but this\n', '    is not guaranteed."""\n', '    if isclass(object) or ismethod(object) or isfunction(object):\n', '        # mutual exclusion\n', '        return False\n', '    tp = type(object)\n', '    return hasattr(tp, "__set__") or hasattr(tp, "__delete__")\n', '\n', "if hasattr(types, 'MemberDescriptorType'):\n", '    # CPython and equivalent\n', '    def ismemberdescriptor(object):\n', '        """Return true if the object is a member descriptor.\n', '\n', '        Member descriptors are specialized descriptors defined in extension\n', '        modules."""\n', '        return isinstance(object, types.MemberDescriptorType)\n', 'else:\n', '    # Other implementations\n', '    def ismemberdescriptor(object):\n', '        """Return true if the object is a member descriptor.\n', '\n', '        Member descriptors are specialized descriptors defined in extension\n', '        modules."""\n', '        return False\n', '\n', "if hasattr(types, 'GetSetDescriptorType'):\n", '    # CPython and equivalent\n', '    def isgetsetdescriptor(object):\n', '        """Return true if the object is a getset descriptor.\n', '\n', '        getset descriptors are specialized descriptors defined in extension\n', '        modules."""\n', '        return isinstance(object, types.GetSetDescriptorType)\n', 'else:\n', '    # Other implementations\n', '    def isgetsetdescriptor(object):\n', '        """Return true if the object is a getset descriptor.\n', '\n', '        getset descriptors are specialized descriptors defined in extension\n', '        modules."""\n', '        return False\n', '\n', 'def isfunction(object):\n', '    """Return true if the object is a user-defined function.\n', '\n', '    Function objects provide these attributes:\n', '        __doc__         documentation string\n', '        __name__        name with which this function was defined\n', '        __code__        code object containing compiled function bytecode\n', '        __defaults__    tuple of any default values for arguments\n', '        __globals__     global namespace in which this function was defined\n', '        __annotations__ dict of parameter annotations\n', '        __kwdefaults__  dict of keyword only parameters with defaults"""\n', '    return isinstance(object, types.FunctionType)\n', '\n', 'def _has_code_flag(f, flag):\n', '    """Return true if ``f`` is a function (or a method or functools.partial\n', '    wrapper wrapping a function) whose code object has the given ``flag``\n', '    set in its flags."""\n', '    while ismethod(f):\n', '        f = f.__func__\n', '    f = functools._unwrap_partial(f)\n', '    if not (isfunction(f) or _signature_is_functionlike(f)):\n', '        return False\n', '    return bool(f.__code__.co_flags & flag)\n', '\n', 'def isgeneratorfunction(obj):\n', '    """Return true if the object is a user-defined generator function.\n', '\n', '    Generator function objects provide the same attributes as functions.\n', '    See help(isfunction) for a list of attributes."""\n', '    return _has_code_flag(obj, CO_GENERATOR)\n', '\n', 'def iscoroutinefunction(obj):\n', '    """Return true if the object is a coroutine function.\n', '\n', '    Coroutine functions are defined with "async def" syntax.\n', '    """\n', '    return _has_code_flag(obj, CO_COROUTINE)\n', '\n', 'def isasyncgenfunction(obj):\n', '    """Return true if the object is an asynchronous generator function.\n', '\n', '    Asynchronous generator functions are defined with "async def"\n', '    syntax and have "yield" expressions in their body.\n', '    """\n', '    return _has_code_flag(obj, CO_ASYNC_GENERATOR)\n', '\n', 'def isasyncgen(object):\n', '    """Return true if the object is an asynchronous generator."""\n', '    return isinstance(object, types.AsyncGeneratorType)\n', '\n', 'def isgenerator(object):\n', '    """Return true if the object is a generator.\n', '\n', '    Generator objects provide these attributes:\n', '        __iter__        defined to support iteration over container\n', '        close           raises a new GeneratorExit exception inside the\n', '                        generator to terminate the iteration\n', '        gi_code         code object\n', '        gi_frame        frame object or possibly None once the generator has\n', '                        been exhausted\n', '        gi_running      set to 1 when generator is executing, 0 otherwise\n', '        next            return the next item from the container\n', '        send            resumes the generator and "sends" a value that becomes\n', '                        the result of the current yield-expression\n', '        throw           used to raise an exception inside the generator"""\n', '    return isinstance(object, types.GeneratorType)\n', '\n', 'def iscoroutine(object):\n', '    """Return true if the object is a coroutine."""\n', '    return isinstance(object, types.CoroutineType)\n', '\n', 'def isawaitable(object):\n', '    """Return true if object can be passed to an ``await`` expression."""\n', '    return (isinstance(object, types.CoroutineType) or\n', '            isinstance(object, types.GeneratorType) and\n', '                bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or\n', '            isinstance(object, collections.abc.Awaitable))\n', '\n', 'def istraceback(object):\n', '    """Return true if the object is a traceback.\n', '\n', '    Traceback objects provide these attributes:\n', '        tb_frame        frame object at this level\n', '        tb_lasti        index of last attempted instruction in bytecode\n', '        tb_lineno       current line number in Python source code\n', '        tb_next         next inner traceback object (called by this level)"""\n', '    return isinstance(object, types.TracebackType)\n', '\n', 'def isframe(object):\n', '    """Return true if the object is a frame object.\n', '\n', '    Frame objects provide these attributes:\n', "        f_back          next outer frame object (this frame's caller)\n", '        f_builtins      built-in namespace seen by this frame\n', '        f_code          code object being executed in this frame\n', '        f_globals       global namespace seen by this frame\n', '        f_lasti         index of last attempted instruction in bytecode\n', '        f_lineno        current line number in Python source code\n', '        f_locals        local namespace seen by this frame\n', '        f_trace         tracing function for this frame, or None"""\n', '    return isinstance(object, types.FrameType)\n', '\n', 'def iscode(object):\n', '    """Return true if the object is a code object.\n', '\n', '    Code objects provide these attributes:\n', '        co_argcount         number of arguments (not including *, ** args\n', '                            or keyword only arguments)\n', '        co_code             string of raw compiled bytecode\n', '        co_cellvars         tuple of names of cell variables\n', '        co_consts           tuple of constants used in the bytecode\n', '        co_filename         name of file in which this code object was created\n', '        co_firstlineno      number of first line in Python source code\n', '        co_flags            bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg\n', '                            | 16=nested | 32=generator | 64=nofree | 128=coroutine\n', '                            | 256=iterable_coroutine | 512=async_generator\n', '        co_freevars         tuple of names of free variables\n', '        co_posonlyargcount  number of positional only arguments\n', '        co_kwonlyargcount   number of keyword only arguments (not including ** arg)\n', '        co_lnotab           encoded mapping of line numbers to bytecode indices\n', '        co_name             name with which this code object was defined\n', '        co_names            tuple of names other than arguments and function locals\n', '        co_nlocals          number of local variables\n', '        co_stacksize        virtual machine stack space required\n', '        co_varnames         tuple of names of arguments and local variables"""\n', '    return isinstance(object, types.CodeType)\n', '\n', 'def isbuiltin(object):\n', '    """Return true if the object is a built-in function or method.\n', '\n', '    Built-in functions and methods provide these attributes:\n', '        __doc__         documentation string\n', '        __name__        original name of this function or method\n', '        __self__        instance to which a method is bound, or None"""\n', '    return isinstance(object, types.BuiltinFunctionType)\n', '\n', 'def isroutine(object):\n', '    """Return true if the object is any kind of function or method."""\n', '    return (isbuiltin(object)\n', '            or isfunction(object)\n', '            or ismethod(object)\n', '            or ismethoddescriptor(object))\n', '\n', 'def isabstract(object):\n', '    """Return true if the object is an abstract base class (ABC)."""\n', '    if not isinstance(object, type):\n', '        return False\n', '    if object.__flags__ & TPFLAGS_IS_ABSTRACT:\n', '        return True\n', '    if not issubclass(type(object), abc.ABCMeta):\n', '        return False\n', "    if hasattr(object, '__abstractmethods__'):\n", '        # It looks like ABCMeta.__new__ has finished running;\n', '        # TPFLAGS_IS_ABSTRACT should have been accurate.\n', '        return False\n', "    # It looks like ABCMeta.__new__ has not finished running yet; we're\n", "    # probably in __init_subclass__. We'll look for abstractmethods manually.\n", '    for name, value in object.__dict__.items():\n', '        if getattr(value, "__isabstractmethod__", False):\n', '            return True\n', '    for base in object.__bases__:\n', '        for name in getattr(base, "__abstractmethods__", ()):\n', '            value = getattr(object, name, None)\n', '            if getattr(value, "__isabstractmethod__", False):\n', '                return True\n', '    return False\n', '\n', 'def getmembers(object, predicate=None):\n', '    """Return all members of an object as (name, value) pairs sorted by name.\n', '    Optionally, only return members that satisfy a given predicate."""\n', '    if isclass(object):\n', '        mro = (object,) + getmro(object)\n', '    else:\n', '        mro = ()\n', '    results = []\n', '    processed = set()\n', '    names = dir(object)\n', '    # :dd any DynamicClassAttributes to the list of names if object is a class;\n', '    # this may result in duplicate entries if, for example, a virtual\n', '    # attribute with the same name as a DynamicClassAttribute exists\n', '    try:\n', '        for base in object.__bases__:\n', '            for k, v in base.__dict__.items():\n', '                if isinstance(v, types.DynamicClassAttribute):\n', '                    names.append(k)\n', '    except AttributeError:\n', '        pass\n', '    for key in names:\n', "        # First try to get the value via getattr.  Some descriptors don't\n", '        # like calling their __get__ (see bug #1785), so fall back to\n', '        # looking in the __dict__.\n', '        try:\n', '            value = getattr(object, key)\n', '            # handle the duplicate key\n', '            if key in processed:\n', '                raise AttributeError\n', '        except AttributeError:\n', '            for base in mro:\n', '                if key in base.__dict__:\n', '                    value = base.__dict__[key]\n', '                    break\n', '            else:\n', '                # could be a (currently) missing slot member, or a buggy\n', '                # __dir__; discard and move on\n', '                continue\n', '        if not predicate or predicate(value):\n', '            results.append((key, value))\n', '        processed.add(key)\n', '    results.sort(key=lambda pair: pair[0])\n', '    return results\n', '\n', "Attribute = namedtuple('Attribute', 'name kind defining_class object')\n", '\n', 'def classify_class_attrs(cls):\n', '    """Return list of attribute-descriptor tuples.\n', '\n', '    For each name in dir(cls), the return list contains a 4-tuple\n', '    with these elements:\n', '\n', '        0. The name (a string).\n', '\n', '        1. The kind of attribute this is, one of these strings:\n', "               'class method'    created via classmethod()\n", "               'static method'   created via staticmethod()\n", "               'property'        created via property()\n", "               'method'          any other flavor of method or descriptor\n", "               'data'            not a method\n", '\n', '        2. The class which defined this attribute (a class).\n', '\n', '        3. The object as obtained by calling getattr; if this fails, or if the\n', "           resulting object does not live anywhere in the class' mro (including\n", "           metaclasses) then the object is looked up in the defining class's\n", '           dict (found by walking the mro).\n', '\n', '    If one of the items in dir(cls) is stored in the metaclass it will now\n', '    be discovered and not have None be listed as the class in which it was\n', '    defined.  Any items whose home class cannot be discovered are skipped.\n', '    """\n', '\n', '    mro = getmro(cls)\n', '    metamro = getmro(type(cls)) # for attributes stored in the metaclass\n', '    metamro = tuple(cls for cls in metamro if cls not in (type, object))\n', '    class_bases = (cls,) + mro\n', '    all_bases = class_bases + metamro\n', '    names = dir(cls)\n', '    # :dd any DynamicClassAttributes to the list of names;\n', '    # this may result in duplicate entries if, for example, a virtual\n', '    # attribute with the same name as a DynamicClassAttribute exists.\n', '    for base in mro:\n', '        for k, v in base.__dict__.items():\n', '            if isinstance(v, types.DynamicClassAttribute) and v.fget is not None:\n', '                names.append(k)\n', '    result = []\n', '    processed = set()\n', '\n', '    for name in names:\n', '        # Get the object associated with the name, and where it was defined.\n', '        # Normal objects will be looked up with both getattr and directly in\n', "        # its class' dict (in case getattr fails [bug #1785], and also to look\n", '        # for a docstring).\n', '        # For DynamicClassAttributes on the second pass we only look in the\n', "        # class's dict.\n", '        #\n', '        # Getting an obj from the __dict__ sometimes reveals more than\n', '        # using getattr.  Static and class methods are dramatic examples.\n', '        homecls = None\n', '        get_obj = None\n', '        dict_obj = None\n', '        if name not in processed:\n', '            try:\n', "                if name == '__dict__':\n", '                    raise Exception("__dict__ is special, don\'t want the proxy")\n', '                get_obj = getattr(cls, name)\n', '            except Exception as exc:\n', '                pass\n', '            else:\n', '                homecls = getattr(get_obj, "__objclass__", homecls)\n', '                if homecls not in class_bases:\n', '                    # if the resulting object does not live somewhere in the\n', '                    # mro, drop it and search the mro manually\n', '                    homecls = None\n', '                    last_cls = None\n', '                    # first look in the classes\n', '                    for srch_cls in class_bases:\n', '                        srch_obj = getattr(srch_cls, name, None)\n', '                        if srch_obj is get_obj:\n', '                            last_cls = srch_cls\n', '                    # then check the metaclasses\n', '                    for srch_cls in metamro:\n', '                        try:\n', '                            srch_obj = srch_cls.__getattr__(cls, name)\n', '                        except AttributeError:\n', '                            continue\n', '                        if srch_obj is get_obj:\n', '                            last_cls = srch_cls\n', '                    if last_cls is not None:\n', '                        homecls = last_cls\n', '        for base in all_bases:\n', '            if name in base.__dict__:\n', '                dict_obj = base.__dict__[name]\n', '                if homecls not in metamro:\n', '                    homecls = base\n', '                break\n', '        if homecls is None:\n', '            # unable to locate the attribute anywhere, most likely due to\n', '            # buggy custom __dir__; discard and move on\n', '            continue\n', '        obj = get_obj if get_obj is not None else dict_obj\n', '        # Classify the object or its descriptor.\n', '        if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):\n', '            kind = "static method"\n', '            obj = dict_obj\n', '        elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):\n', '            kind = "class method"\n', '            obj = dict_obj\n', '        elif isinstance(dict_obj, property):\n', '            kind = "property"\n', '            obj = dict_obj\n', '        elif isroutine(obj):\n', '            kind = "method"\n', '        else:\n', '            kind = "data"\n', '        result.append(Attribute(name, kind, homecls, obj))\n', '        processed.add(name)\n', '    return result\n', '\n', '# ----------------------------------------------------------- class helpers\n', '\n', 'def getmro(cls):\n', '    "Return tuple of base classes (including cls) in method resolution order."\n', '    return cls.__mro__\n', '\n', '# -------------------------------------------------------- function helpers\n', '\n', 'def unwrap(func, *, stop=None):\n', '    """Get the object wrapped by *func*.\n', '\n', '   Follows the chain of :attr:`__wrapped__` attributes returning the last\n', '   object in the chain.\n', '\n', '   *stop* is an optional callback accepting an object in the wrapper chain\n', '   as its sole argument that allows the unwrapping to be terminated early if\n', '   the callback returns a true value. If the callback never returns a true\n', '   value, the last object in the chain is returned as usual. For example,\n', '   :func:`signature` uses this to stop unwrapping if any object in the\n', '   chain has a ``__signature__`` attribute defined.\n', '\n', '   :exc:`ValueError` is raised if a cycle is encountered.\n', '\n', '    """\n', '    if stop is None:\n', '        def _is_wrapper(f):\n', "            return hasattr(f, '__wrapped__')\n", '    else:\n', '        def _is_wrapper(f):\n', "            return hasattr(f, '__wrapped__') and not stop(f)\n", '    f = func  # remember the original func for error reporting\n', '    # Memoise by id to tolerate non-hashable objects, but store objects to\n', "    # ensure they aren't destroyed, which would allow their IDs to be reused.\n", '    memo = {id(f): f}\n', '    recursion_limit = sys.getrecursionlimit()\n', '    while _is_wrapper(func):\n', '        func = func.__wrapped__\n', '        id_func = id(func)\n', '        if (id_func in memo) or (len(memo) >= recursion_limit):\n', "            raise ValueError('wrapper loop when unwrapping {!r}'.format(f))\n", '        memo[id_func] = func\n', '    return func\n', '\n', '# -------------------------------------------------- source code extraction\n', 'def indentsize(line):\n', '    """Return the indent size, in spaces, at the start of a line of text."""\n', '    expline = line.expandtabs()\n', '    return len(expline) - len(expline.lstrip())\n', '\n', 'def _findclass(func):\n', '    cls = sys.modules.get(func.__module__)\n', '    if cls is None:\n', '        return None\n', "    for name in func.__qualname__.split('.')[:-1]:\n", '        cls = getattr(cls, name)\n', '    if not isclass(cls):\n', '        return None\n', '    return cls\n', '\n', 'def _finddoc(obj):\n', '    if isclass(obj):\n', '        for base in obj.__mro__:\n', '            if base is not object:\n', '                try:\n', '                    doc = base.__doc__\n', '                except AttributeError:\n', '                    continue\n', '                if doc is not None:\n', '                    return doc\n', '        return None\n', '\n', '    if ismethod(obj):\n', '        name = obj.__func__.__name__\n', '        self = obj.__self__\n', '        if (isclass(self) and\n', "            getattr(getattr(self, name, None), '__func__') is obj.__func__):\n", '            # classmethod\n', '            cls = self\n', '        else:\n', '            cls = self.__class__\n', '    elif isfunction(obj):\n', '        name = obj.__name__\n', '        cls = _findclass(obj)\n', '        if cls is None or getattr(cls, name) is not obj:\n', '            return None\n', '    elif isbuiltin(obj):\n', '        name = obj.__name__\n', '        self = obj.__self__\n', '        if (isclass(self) and\n', "            self.__qualname__ + '.' + name == obj.__qualname__):\n", '            # classmethod\n', '            cls = self\n', '        else:\n', '            cls = self.__class__\n', '    # Should be tested before isdatadescriptor().\n', '    elif isinstance(obj, property):\n', '        func = obj.fget\n', '        name = func.__name__\n', '        cls = _findclass(func)\n', '        if cls is None or getattr(cls, name) is not obj:\n', '            return None\n', '    elif ismethoddescriptor(obj) or isdatadescriptor(obj):\n', '        name = obj.__name__\n', '        cls = obj.__objclass__\n', '        if getattr(cls, name) is not obj:\n', '            return None\n', '        if ismemberdescriptor(obj):\n', "            slots = getattr(cls, '__slots__', None)\n", '            if isinstance(slots, dict) and name in slots:\n', '                return slots[name]\n', '    else:\n', '        return None\n', '    for base in cls.__mro__:\n', '        try:\n', '            doc = getattr(base, name).__doc__\n', '        except AttributeError:\n', '            continue\n', '        if doc is not None:\n', '            return doc\n', '    return None\n', '\n', 'def getdoc(object):\n', '    """Get the documentation string for an object.\n', '\n', '    All tabs are expanded to spaces.  To clean up docstrings that are\n', '    indented to line up with blocks of code, any whitespace than can be\n', '    uniformly removed from the second line onwards is removed."""\n', '    try:\n', '        doc = object.__doc__\n', '    except AttributeError:\n', '        return None\n', '    if doc is None:\n', '        try:\n', '            doc = _finddoc(object)\n', '        except (AttributeError, TypeError):\n', '            return None\n', '    if not isinstance(doc, str):\n', '        return None\n', '    return cleandoc(doc)\n', '\n', 'def cleandoc(doc):\n', '    """Clean up indentation from docstrings.\n', '\n', '    Any whitespace that can be uniformly removed from the second line\n', '    onwards is removed."""\n', '    try:\n', "        lines = doc.expandtabs().split('\\n')\n", '    except UnicodeError:\n', '        return None\n', '    else:\n', '        # Find minimum indentation of any non-blank lines after first line.\n', '        margin = sys.maxsize\n', '        for line in lines[1:]:\n', '            content = len(line.lstrip())\n', '            if content:\n', '                indent = len(line) - content\n', '                margin = min(margin, indent)\n', '        # Remove indentation.\n', '        if lines:\n', '            lines[0] = lines[0].lstrip()\n', '        if margin < sys.maxsize:\n', '            for i in range(1, len(lines)): lines[i] = lines[i][margin:]\n', '        # Remove any trailing or leading blank lines.\n', '        while lines and not lines[-1]:\n', '            lines.pop()\n', '        while lines and not lines[0]:\n', '            lines.pop(0)\n', "        return '\\n'.join(lines)\n", '\n', 'def getfile(object):\n', '    """Work out which source or compiled file an object was defined in."""\n', '    if ismodule(object):\n', "        if getattr(object, '__file__', None):\n", '            return object.__file__\n', "        raise TypeError('{!r} is a built-in module'.format(object))\n", '    if isclass(object):\n', "        if hasattr(object, '__module__'):\n", '            module = sys.modules.get(object.__module__)\n', "            if getattr(module, '__file__', None):\n", '                return module.__file__\n', "            if object.__module__ == '__main__':\n", "                raise OSError('source code not available')\n", "        raise TypeError('{!r} is a built-in class'.format(object))\n", '    if ismethod(object):\n', '        object = object.__func__\n', '    if isfunction(object):\n', '        object = object.__code__\n', '    if istraceback(object):\n', '        object = object.tb_frame\n', '    if isframe(object):\n', '        object = object.f_code\n', '    if iscode(object):\n', '        return object.co_filename\n', "    raise TypeError('module, class, method, function, traceback, frame, or '\n", "                    'code object was expected, got {}'.format(\n", '                    type(object).__name__))\n', '\n', 'def getmodulename(path):\n', '    """Return the module name for a given file, or None."""\n', '    fname = os.path.basename(path)\n', '    # Check for paths that look like an actual module file\n', '    suffixes = [(-len(suffix), suffix)\n', '                    for suffix in importlib.machinery.all_suffixes()]\n', '    suffixes.sort() # try longest suffixes first, in case they overlap\n', '    for neglen, suffix in suffixes:\n', '        if fname.endswith(suffix):\n', '            return fname[:neglen]\n', '    return None\n', '\n', 'def getsourcefile(object):\n', '    """Return the filename that can be used to locate an object\'s source.\n', '    Return None if no way can be identified to get the source.\n', '    """\n', '    filename = getfile(object)\n', '    all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]\n', '    all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]\n', '    if any(filename.endswith(s) for s in all_bytecode_suffixes):\n', '        filename = (os.path.splitext(filename)[0] +\n', '                    importlib.machinery.SOURCE_SUFFIXES[0])\n', '    elif any(filename.endswith(s) for s in\n', '                 importlib.machinery.EXTENSION_SUFFIXES):\n', '        return None\n', '    if os.path.exists(filename):\n', '        return filename\n', '    # only return a non-existent filename if the module has a PEP 302 loader\n', '    module = getmodule(object, filename)\n', "    if getattr(module, '__loader__', None) is not None:\n", '        return filename\n', '    elif getattr(getattr(module, "__spec__", None), "loader", None) is not None:\n', '        return filename\n', '    # or it is in the linecache\n', '    elif filename in linecache.cache:\n', '        return filename\n', '\n', 'def getabsfile(object, _filename=None):\n', '    """Return an absolute path to the source or compiled file for an object.\n', '\n', '    The idea is for each object to have a unique origin, so this routine\n', '    normalizes the result as much as possible."""\n', '    if _filename is None:\n', '        _filename = getsourcefile(object) or getfile(object)\n', '    return os.path.normcase(os.path.abspath(_filename))\n', '\n', 'modulesbyfile = {}\n', '_filesbymodname = {}\n', '\n', 'def getmodule(object, _filename=None):\n', '    """Return the module an object was defined in, or None if not found."""\n', '    if ismodule(object):\n', '        return object\n', "    if hasattr(object, '__module__'):\n", '        return sys.modules.get(object.__module__)\n', '    # Try the filename to modulename cache\n', '    if _filename is not None and _filename in modulesbyfile:\n', '        return sys.modules.get(modulesbyfile[_filename])\n', '    # Try the cache again with the absolute file name\n', '    try:\n', '        file = getabsfile(object, _filename)\n', '    except (TypeError, FileNotFoundError):\n', '        return None\n', '    if file in modulesbyfile:\n', '        return sys.modules.get(modulesbyfile[file])\n', '    # Update the filename to module name cache and check yet again\n', '    # Copy sys.modules in order to cope with changes while iterating\n', '    for modname, module in sys.modules.copy().items():\n', "        if ismodule(module) and hasattr(module, '__file__'):\n", '            f = module.__file__\n', '            if f == _filesbymodname.get(modname, None):\n', '                # Have already mapped this module, so skip it\n', '                continue\n', '            _filesbymodname[modname] = f\n', '            f = getabsfile(module)\n', '            # Always map to the name the module knows itself by\n', '            modulesbyfile[f] = modulesbyfile[\n', '                os.path.realpath(f)] = module.__name__\n', '    if file in modulesbyfile:\n', '        return sys.modules.get(modulesbyfile[file])\n', '    # Check the main module\n', "    main = sys.modules['__main__']\n", "    if not hasattr(object, '__name__'):\n", '        return None\n', '    if hasattr(main, object.__name__):\n', '        mainobject = getattr(main, object.__name__)\n', '        if mainobject is object:\n', '            return main\n', '    # Check builtins\n', "    builtin = sys.modules['builtins']\n", '    if hasattr(builtin, object.__name__):\n', '        builtinobject = getattr(builtin, object.__name__)\n', '        if builtinobject is object:\n', '            return builtin\n', '\n', '\n', 'class ClassFoundException(Exception):\n', '    pass\n', '\n', '\n', 'class _ClassFinder(ast.NodeVisitor):\n', '\n', '    def __init__(self, qualname):\n', '        self.stack = []\n', '        self.qualname = qualname\n', '\n', '    def visit_FunctionDef(self, node):\n', '        self.stack.append(node.name)\n', "        self.stack.append('<locals>')\n", '        self.generic_visit(node)\n', '        self.stack.pop()\n', '        self.stack.pop()\n', '\n', '    visit_AsyncFunctionDef = visit_FunctionDef\n', '\n', '    def visit_ClassDef(self, node):\n', '        self.stack.append(node.name)\n', "        if self.qualname == '.'.join(self.stack):\n", '            # Return the decorator for the class if present\n', '            if node.decorator_list:\n', '                line_number = node.decorator_list[0].lineno\n', '            else:\n', '                line_number = node.lineno\n', '\n', '            # decrement by one since lines starts with indexing by zero\n', '            line_number -= 1\n', '            raise ClassFoundException(line_number)\n', '        self.generic_visit(node)\n', '        self.stack.pop()\n', '\n', '\n', 'def findsource(object):\n', '    """Return the entire source file and starting line number for an object.\n', '\n', '    The argument may be a module, class, method, function, traceback, frame,\n', '    or code object.  The source code is returned as a list of all the lines\n', '    in the file and the line number indexes a line in that list.  An OSError\n', '    is raised if the source code cannot be retrieved."""\n', '\n', '    file = getsourcefile(object)\n', '    if file:\n', '        # Invalidate cache if needed.\n', '        linecache.checkcache(file)\n', '    else:\n', '        file = getfile(object)\n', '        # Allow filenames in form of "<something>" to pass through.\n', '        # `doctest` monkeypatches `linecache` module to enable\n', '        # inspection, so let `linecache.getlines` to be called.\n', "        if not (file.startswith('<') and file.endswith('>')):\n", "            raise OSError('source code not available')\n", '\n', '    module = getmodule(object, file)\n', '    if module:\n', '        lines = linecache.getlines(file, module.__dict__)\n', '    else:\n', '        lines = linecache.getlines(file)\n', '    if not lines:\n', "        raise OSError('could not get source code')\n", '\n', '    if ismodule(object):\n', '        return lines, 0\n', '\n', '    if isclass(object):\n', '        qualname = object.__qualname__\n', "        source = ''.join(lines)\n", '        tree = ast.parse(source)\n', '        class_finder = _ClassFinder(qualname)\n', '        try:\n', '            class_finder.visit(tree)\n', '        except ClassFoundException as e:\n', '            line_number = e.args[0]\n', '            return lines, line_number\n', '        else:\n', "            raise OSError('could not find class definition')\n", '\n', '    if ismethod(object):\n', '        object = object.__func__\n', '    if isfunction(object):\n', '        object = object.__code__\n', '    if istraceback(object):\n', '        object = object.tb_frame\n', '    if isframe(object):\n', '        object = object.f_code\n', '    if iscode(object):\n', "        if not hasattr(object, 'co_firstlineno'):\n", "            raise OSError('could not find function definition')\n", '        lnum = object.co_firstlineno - 1\n', "        pat = re.compile(r'^(\\s*def\\s)|(\\s*async\\s+def\\s)|(.*(?<!\\w)lambda(:|\\s))|^(\\s*@)')\n", '        while lnum > 0:\n', '            try:\n', '                line = lines[lnum]\n', '            except IndexError:\n', "                raise OSError('lineno is out of bounds')\n", '            if pat.match(line):\n', '                break\n', '            lnum = lnum - 1\n', '        return lines, lnum\n', "    raise OSError('could not find code object')\n", '\n', 'def getcomments(object):\n', '    """Get lines of comments immediately preceding an object\'s source code.\n', '\n', "    Returns None when source can't be found.\n", '    """\n', '    try:\n', '        lines, lnum = findsource(object)\n', '    except (OSError, TypeError):\n', '        return None\n', '\n', '    if ismodule(object):\n', '        # Look for a comment block at the top of the file.\n', '        start = 0\n', "        if lines and lines[0][:2] == '#!': start = 1\n", "        while start < len(lines) and lines[start].strip() in ('', '#'):\n", '            start = start + 1\n', "        if start < len(lines) and lines[start][:1] == '#':\n", '            comments = []\n', '            end = start\n', "            while end < len(lines) and lines[end][:1] == '#':\n", '                comments.append(lines[end].expandtabs())\n', '                end = end + 1\n', "            return ''.join(comments)\n", '\n', '    # Look for a preceding block of comments at the same indentation.\n', '    elif lnum > 0:\n', '        indent = indentsize(lines[lnum])\n', '        end = lnum - 1\n', "        if end >= 0 and lines[end].lstrip()[:1] == '#' and \\\n", '            indentsize(lines[end]) == indent:\n', '            comments = [lines[end].expandtabs().lstrip()]\n', '            if end > 0:\n', '                end = end - 1\n', '                comment = lines[end].expandtabs().lstrip()\n', "                while comment[:1] == '#' and indentsize(lines[end]) == indent:\n", '                    comments[:0] = [comment]\n', '                    end = end - 1\n', '                    if end < 0: break\n', '                    comment = lines[end].expandtabs().lstrip()\n', "            while comments and comments[0].strip() == '#':\n", '                comments[:1] = []\n', "            while comments and comments[-1].strip() == '#':\n", '                comments[-1:] = []\n', "            return ''.join(comments)\n", '\n', 'class EndOfBlock(Exception): pass\n', '\n', 'class BlockFinder:\n', '    """Provide a tokeneater() method to detect the end of a code block."""\n', '    def __init__(self):\n', '        self.indent = 0\n', '        self.islambda = False\n', '        self.started = False\n', '        self.passline = False\n', '        self.indecorator = False\n', '        self.decoratorhasargs = False\n', '        self.last = 1\n', '        self.body_col0 = None\n', '\n', '    def tokeneater(self, type, token, srowcol, erowcol, line):\n', '        if not self.started and not self.indecorator:\n', '            # skip any decorators\n', '            if token == "@":\n', '                self.indecorator = True\n', '            # look for the first "def", "class" or "lambda"\n', '            elif token in ("def", "class", "lambda"):\n', '                if token == "lambda":\n', '                    self.islambda = True\n', '                self.started = True\n', '            self.passline = True    # skip to the end of the line\n', '        elif token == "(":\n', '            if self.indecorator:\n', '                self.decoratorhasargs = True\n', '        elif token == ")":\n', '            if self.indecorator:\n', '                self.indecorator = False\n', '                self.decoratorhasargs = False\n', '        elif type == tokenize.NEWLINE:\n', '            self.passline = False   # stop skipping when a NEWLINE is seen\n', '            self.last = srowcol[0]\n', '            if self.islambda:       # lambdas always end at the first NEWLINE\n', '                raise EndOfBlock\n', '            # hitting a NEWLINE when in a decorator without args\n', '            # ends the decorator\n', '            if self.indecorator and not self.decoratorhasargs:\n', '                self.indecorator = False\n', '        elif self.passline:\n', '            pass\n', '        elif type == tokenize.INDENT:\n', '            if self.body_col0 is None and self.started:\n', '                self.body_col0 = erowcol[1]\n', '            self.indent = self.indent + 1\n', '            self.passline = True\n', '        elif type == tokenize.DEDENT:\n', '            self.indent = self.indent - 1\n', '            # the end of matching indent/dedent pairs end a block\n', '            # (note that this only works for "def"/"class" blocks,\n', '            #  not e.g. for "if: else:" or "try: finally:" blocks)\n', '            if self.indent <= 0:\n', '                raise EndOfBlock\n', '        elif type == tokenize.COMMENT:\n', '            if self.body_col0 is not None and srowcol[1] >= self.body_col0:\n', '                # Include comments if indented at least as much as the block\n', '                self.last = srowcol[0]\n', '        elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):\n', '            # any other token on the same indentation level end the previous\n', '            # block as well, except the pseudo-tokens COMMENT and NL.\n', '            raise EndOfBlock\n', '\n', 'def getblock(lines):\n', '    """Extract the block of code at the top of the given list of lines."""\n', '    blockfinder = BlockFinder()\n', '    try:\n', '        tokens = tokenize.generate_tokens(iter(lines).__next__)\n', '        for _token in tokens:\n', '            blockfinder.tokeneater(*_token)\n', '    except (EndOfBlock, IndentationError):\n', '        pass\n', '    return lines[:blockfinder.last]\n', '\n', 'def getsourcelines(object):\n', '    """Return a list of source lines and starting line number for an object.\n', '\n', '    The argument may be a module, class, method, function, traceback, frame,\n', '    or code object.  The source code is returned as a list of the lines\n', '    corresponding to the object and the line number indicates where in the\n', '    original source file the first line of code was found.  An OSError is\n', '    raised if the source code cannot be retrieved."""\n', '    object = unwrap(object)\n', '    lines, lnum = findsource(object)\n', '\n', '    if istraceback(object):\n', '        object = object.tb_frame\n', '\n', '    # for module or frame that corresponds to module, return all source lines\n', '    if (ismodule(object) or\n', '        (isframe(object) and object.f_code.co_name == "<module>")):\n', '        return lines, 0\n', '    else:\n', '        return getblock(lines[lnum:]), lnum + 1\n', '\n', 'def getsource(object):\n', '    """Return the text of the source code for an object.\n', '\n', '    The argument may be a module, class, method, function, traceback, frame,\n', '    or code object.  The source code is returned as a single string.  An\n', '    OSError is raised if the source code cannot be retrieved."""\n', '    lines, lnum = getsourcelines(object)\n', "    return ''.join(lines)\n", '\n', '# --------------------------------------------------- class tree extraction\n', 'def walktree(classes, children, parent):\n', '    """Recursive helper function for getclasstree()."""\n', '    results = []\n', "    classes.sort(key=attrgetter('__module__', '__name__'))\n", '    for c in classes:\n', '        results.append((c, c.__bases__))\n', '        if c in children:\n', '            results.append(walktree(children[c], children, c))\n', '    return results\n', '\n', 'def getclasstree(classes, unique=False):\n', '    """Arrange the given list of classes into a hierarchy of nested lists.\n', '\n', '    Where a nested list appears, it contains classes derived from the class\n', '    whose entry immediately precedes the list.  Each entry is a 2-tuple\n', "    containing a class and a tuple of its base classes.  If the 'unique'\n", '    argument is true, exactly one entry appears in the returned structure\n', '    for each class in the given list.  Otherwise, classes using multiple\n', '    inheritance and their descendants will appear multiple times."""\n', '    children = {}\n', '    roots = []\n', '    for c in classes:\n', '        if c.__bases__:\n', '            for parent in c.__bases__:\n', '                if parent not in children:\n', '                    children[parent] = []\n', '                if c not in children[parent]:\n', '                    children[parent].append(c)\n', '                if unique and parent in classes: break\n', '        elif c not in roots:\n', '            roots.append(c)\n', '    for parent in children:\n', '        if parent not in classes:\n', '            roots.append(parent)\n', '    return walktree(roots, children, None)\n', '\n', '# ------------------------------------------------ argument list extraction\n', "Arguments = namedtuple('Arguments', 'args, varargs, varkw')\n", '\n', 'def getargs(co):\n', '    """Get information about the arguments accepted by a code object.\n', '\n', '    Three things are returned: (args, varargs, varkw), where\n', "    'args' is the list of argument names. Keyword-only arguments are\n", "    appended. 'varargs' and 'varkw' are the names of the * and **\n", '    arguments or None."""\n', '    if not iscode(co):\n', "        raise TypeError('{!r} is not a code object'.format(co))\n", '\n', '    names = co.co_varnames\n', '    nargs = co.co_argcount\n', '    nkwargs = co.co_kwonlyargcount\n', '    args = list(names[:nargs])\n', '    kwonlyargs = list(names[nargs:nargs+nkwargs])\n', '    step = 0\n', '\n', '    nargs += nkwargs\n', '    varargs = None\n', '    if co.co_flags & CO_VARARGS:\n', '        varargs = co.co_varnames[nargs]\n', '        nargs = nargs + 1\n', '    varkw = None\n', '    if co.co_flags & CO_VARKEYWORDS:\n', '        varkw = co.co_varnames[nargs]\n', '    return Arguments(args + kwonlyargs, varargs, varkw)\n', '\n', "ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')\n", '\n', 'def getargspec(func):\n', '    """Get the names and default values of a function\'s parameters.\n', '\n', '    A tuple of four things is returned: (args, varargs, keywords, defaults).\n', "    'args' is a list of the argument names, including keyword-only argument names.\n", "    'varargs' and 'keywords' are the names of the * and ** parameters or None.\n", "    'defaults' is an n-tuple of the default values of the last n parameters.\n", '\n', '    This function is deprecated, as it does not support annotations or\n', '    keyword-only parameters and will raise ValueError if either is present\n', '    on the supplied callable.\n', '\n', '    For a more structured introspection API, use inspect.signature() instead.\n', '\n', '    Alternatively, use getfullargspec() for an API with a similar namedtuple\n', '    based interface, but full support for annotations and keyword-only\n', '    parameters.\n', '\n', '    Deprecated since Python 3.5, use `inspect.getfullargspec()`.\n', '    """\n', '    warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "\n', '                  "use inspect.signature() or inspect.getfullargspec()",\n', '                  DeprecationWarning, stacklevel=2)\n', '    args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \\\n', '        getfullargspec(func)\n', '    if kwonlyargs or ann:\n', '        raise ValueError("Function has keyword-only parameters or annotations"\n', '                         ", use inspect.signature() API which can support them")\n', '    return ArgSpec(args, varargs, varkw, defaults)\n', '\n', "FullArgSpec = namedtuple('FullArgSpec',\n", "    'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')\n", '\n', 'def getfullargspec(func):\n', '    """Get the names and default values of a callable object\'s parameters.\n', '\n', '    A tuple of seven things is returned:\n', '    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).\n', "    'args' is a list of the parameter names.\n", "    'varargs' and 'varkw' are the names of the * and ** parameters or None.\n", "    'defaults' is an n-tuple of the default values of the last n parameters.\n", "    'kwonlyargs' is a list of keyword-only parameter names.\n", "    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.\n", "    'annotations' is a dictionary mapping parameter names to annotations.\n", '\n', '    Notable differences from inspect.signature():\n', '      - the "self" parameter is always reported, even for bound methods\n', '      - wrapper chains defined by __wrapped__ *not* unwrapped automatically\n', '    """\n', '    try:\n', '        # Re: `skip_bound_arg=False`\n', '        #\n', '        # There is a notable difference in behaviour between getfullargspec\n', "        # and Signature: the former always returns 'self' parameter for bound\n", '        # methods, whereas the Signature always shows the actual calling\n', '        # signature of the passed object.\n', '        #\n', '        # To simulate this behaviour, we "unbind" bound methods, to trick\n', '        # inspect.signature to always return their first parameter ("self",\n', '        # usually)\n', '\n', '        # Re: `follow_wrapper_chains=False`\n', '        #\n', '        # getfullargspec() historically ignored __wrapped__ attributes,\n', '        # so we ensure that remains the case in 3.3+\n', '\n', '        sig = _signature_from_callable(func,\n', '                                       follow_wrapper_chains=False,\n', '                                       skip_bound_arg=False,\n', '                                       sigcls=Signature,\n', '                                       eval_str=False)\n', '    except Exception as ex:\n', "        # Most of the times 'signature' will raise ValueError.\n", '        # But, it can also raise AttributeError, and, maybe something\n', '        # else. So to be fully backwards compatible, we catch all\n', '        # possible exceptions here, and reraise a TypeError.\n', "        raise TypeError('unsupported callable') from ex\n", '\n', '    args = []\n', '    varargs = None\n', '    varkw = None\n', '    posonlyargs = []\n', '    kwonlyargs = []\n', '    annotations = {}\n', '    defaults = ()\n', '    kwdefaults = {}\n', '\n', '    if sig.return_annotation is not sig.empty:\n', "        annotations['return'] = sig.return_annotation\n", '\n', '    for param in sig.parameters.values():\n', '        kind = param.kind\n', '        name = param.name\n', '\n', '        if kind is _POSITIONAL_ONLY:\n', '            posonlyargs.append(name)\n', '            if param.default is not param.empty:\n', '                defaults += (param.default,)\n', '        elif kind is _POSITIONAL_OR_KEYWORD:\n', '            args.append(name)\n', '            if param.default is not param.empty:\n', '                defaults += (param.default,)\n', '        elif kind is _VAR_POSITIONAL:\n', '            varargs = name\n', '        elif kind is _KEYWORD_ONLY:\n', '            kwonlyargs.append(name)\n', '            if param.default is not param.empty:\n', '                kwdefaults[name] = param.default\n', '        elif kind is _VAR_KEYWORD:\n', '            varkw = name\n', '\n', '        if param.annotation is not param.empty:\n', '            annotations[name] = param.annotation\n', '\n', '    if not kwdefaults:\n', "        # compatibility with 'func.__kwdefaults__'\n", '        kwdefaults = None\n', '\n', '    if not defaults:\n', "        # compatibility with 'func.__defaults__'\n", '        defaults = None\n', '\n', '    return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,\n', '                       kwonlyargs, kwdefaults, annotations)\n', '\n', '\n', "ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')\n", '\n', 'def getargvalues(frame):\n', '    """Get information about arguments passed into a particular frame.\n', '\n', '    A tuple of four things is returned: (args, varargs, varkw, locals).\n', "    'args' is a list of the argument names.\n", "    'varargs' and 'varkw' are the names of the * and ** arguments or None.\n", '    \'locals\' is the locals dictionary of the given frame."""\n', '    args, varargs, varkw = getargs(frame.f_code)\n', '    return ArgInfo(args, varargs, varkw, frame.f_locals)\n', '\n', 'def formatannotation(annotation, base_module=None):\n', "    if getattr(annotation, '__module__', None) == 'typing':\n", '        def repl(match):\n', '            text = match.group()\n', "            return text.removeprefix('typing.')\n", "        return re.sub(r'[\\w\\.]+', repl, repr(annotation))\n", '    if isinstance(annotation, types.GenericAlias):\n', '        return str(annotation)\n', '    if isinstance(annotation, type):\n', "        if annotation.__module__ in ('builtins', base_module):\n", '            return annotation.__qualname__\n', "        return annotation.__module__+'.'+annotation.__qualname__\n", '    return repr(annotation)\n', '\n', 'def formatannotationrelativeto(object):\n', "    module = getattr(object, '__module__', None)\n", '    def _formatannotation(annotation):\n', '        return formatannotation(annotation, module)\n', '    return _formatannotation\n', '\n', 'def formatargspec(args, varargs=None, varkw=None, defaults=None,\n', '                  kwonlyargs=(), kwonlydefaults={}, annotations={},\n', '                  formatarg=str,\n', "                  formatvarargs=lambda name: '*' + name,\n", "                  formatvarkw=lambda name: '**' + name,\n", "                  formatvalue=lambda value: '=' + repr(value),\n", "                  formatreturns=lambda text: ' -> ' + text,\n", '                  formatannotation=formatannotation):\n', '    """Format an argument spec from the values returned by getfullargspec.\n', '\n', '    The first seven arguments are (args, varargs, varkw, defaults,\n', '    kwonlyargs, kwonlydefaults, annotations).  The other five arguments\n', '    are the corresponding optional formatting functions that are called to\n', '    turn names and values into strings.  The last argument is an optional\n', '    function to format the sequence of arguments.\n', '\n', '    Deprecated since Python 3.5: use the `signature` function and `Signature`\n', '    objects.\n', '    """\n', '\n', '    from warnings import warn\n', '\n', '    warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "\n', '         "the `Signature` object directly",\n', '         DeprecationWarning,\n', '         stacklevel=2)\n', '\n', '    def formatargandannotation(arg):\n', '        result = formatarg(arg)\n', '        if arg in annotations:\n', "            result += ': ' + formatannotation(annotations[arg])\n", '        return result\n', '    specs = []\n', '    if defaults:\n', '        firstdefault = len(args) - len(defaults)\n', '    for i, arg in enumerate(args):\n', '        spec = formatargandannotation(arg)\n', '        if defaults and i >= firstdefault:\n', '            spec = spec + formatvalue(defaults[i - firstdefault])\n', '        specs.append(spec)\n', '    if varargs is not None:\n', '        specs.append(formatvarargs(formatargandannotation(varargs)))\n', '    else:\n', '        if kwonlyargs:\n', "            specs.append('*')\n", '    if kwonlyargs:\n', '        for kwonlyarg in kwonlyargs:\n', '            spec = formatargandannotation(kwonlyarg)\n', '            if kwonlydefaults and kwonlyarg in kwonlydefaults:\n', '                spec += formatvalue(kwonlydefaults[kwonlyarg])\n', '            specs.append(spec)\n', '    if varkw is not None:\n', '        specs.append(formatvarkw(formatargandannotation(varkw)))\n', "    result = '(' + ', '.join(specs) + ')'\n", "    if 'return' in annotations:\n", "        result += formatreturns(formatannotation(annotations['return']))\n", '    return result\n', '\n', 'def formatargvalues(args, varargs, varkw, locals,\n', '                    formatarg=str,\n', "                    formatvarargs=lambda name: '*' + name,\n", "                    formatvarkw=lambda name: '**' + name,\n", "                    formatvalue=lambda value: '=' + repr(value)):\n", '    """Format an argument spec from the 4 values returned by getargvalues.\n', '\n', '    The first four arguments are (args, varargs, varkw, locals).  The\n', '    next four arguments are the corresponding optional formatting functions\n', '    that are called to turn names and values into strings.  The ninth\n', '    argument is an optional function to format the sequence of arguments."""\n', '    def convert(name, locals=locals,\n', '                formatarg=formatarg, formatvalue=formatvalue):\n', '        return formatarg(name) + formatvalue(locals[name])\n', '    specs = []\n', '    for i in range(len(args)):\n', '        specs.append(convert(args[i]))\n', '    if varargs:\n', '        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))\n', '    if varkw:\n', '        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))\n', "    return '(' + ', '.join(specs) + ')'\n", '\n', 'def _missing_arguments(f_name, argnames, pos, values):\n', '    names = [repr(name) for name in argnames if name not in values]\n', '    missing = len(names)\n', '    if missing == 1:\n', '        s = names[0]\n', '    elif missing == 2:\n', '        s = "{} and {}".format(*names)\n', '    else:\n', '        tail = ", {} and {}".format(*names[-2:])\n', '        del names[-2:]\n', '        s = ", ".join(names) + tail\n', '    raise TypeError("%s() missing %i required %s argument%s: %s" %\n', '                    (f_name, missing,\n', '                      "positional" if pos else "keyword-only",\n', '                      "" if missing == 1 else "s", s))\n', '\n', 'def _too_many(f_name, args, kwonly, varargs, defcount, given, values):\n', '    atleast = len(args) - defcount\n', '    kwonly_given = len([arg for arg in kwonly if arg in values])\n', '    if varargs:\n', '        plural = atleast != 1\n', '        sig = "at least %d" % (atleast,)\n', '    elif defcount:\n', '        plural = True\n', '        sig = "from %d to %d" % (atleast, len(args))\n', '    else:\n', '        plural = len(args) != 1\n', '        sig = str(len(args))\n', '    kwonly_sig = ""\n', '    if kwonly_given:\n', '        msg = " positional argument%s (and %d keyword-only argument%s)"\n', '        kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,\n', '                             "s" if kwonly_given != 1 else ""))\n', '    raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %\n', '            (f_name, sig, "s" if plural else "", given, kwonly_sig,\n', '             "was" if given == 1 and not kwonly_given else "were"))\n', '\n', 'def getcallargs(func, /, *positional, **named):\n', '    """Get the mapping of arguments to values.\n', '\n', '    A dict is returned, with keys the function argument names (including the\n', '    names of the * and ** arguments, if any), and values the respective bound\n', '    values from \'positional\' and \'named\'."""\n', '    spec = getfullargspec(func)\n', '    args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec\n', '    f_name = func.__name__\n', '    arg2value = {}\n', '\n', '\n', '    if ismethod(func) and func.__self__ is not None:\n', "        # implicit 'self' (or 'cls' for classmethods) argument\n", '        positional = (func.__self__,) + positional\n', '    num_pos = len(positional)\n', '    num_args = len(args)\n', '    num_defaults = len(defaults) if defaults else 0\n', '\n', '    n = min(num_pos, num_args)\n', '    for i in range(n):\n', '        arg2value[args[i]] = positional[i]\n', '    if varargs:\n', '        arg2value[varargs] = tuple(positional[n:])\n', '    possible_kwargs = set(args + kwonlyargs)\n', '    if varkw:\n', '        arg2value[varkw] = {}\n', '    for kw, value in named.items():\n', '        if kw not in possible_kwargs:\n', '            if not varkw:\n', '                raise TypeError("%s() got an unexpected keyword argument %r" %\n', '                                (f_name, kw))\n', '            arg2value[varkw][kw] = value\n', '            continue\n', '        if kw in arg2value:\n', '            raise TypeError("%s() got multiple values for argument %r" %\n', '                            (f_name, kw))\n', '        arg2value[kw] = value\n', '    if num_pos > num_args and not varargs:\n', '        _too_many(f_name, args, kwonlyargs, varargs, num_defaults,\n', '                   num_pos, arg2value)\n', '    if num_pos < num_args:\n', '        req = args[:num_args - num_defaults]\n', '        for arg in req:\n', '            if arg not in arg2value:\n', '                _missing_arguments(f_name, req, True, arg2value)\n', '        for i, arg in enumerate(args[num_args - num_defaults:]):\n', '            if arg not in arg2value:\n', '                arg2value[arg] = defaults[i]\n', '    missing = 0\n', '    for kwarg in kwonlyargs:\n', '        if kwarg not in arg2value:\n', '            if kwonlydefaults and kwarg in kwonlydefaults:\n', '                arg2value[kwarg] = kwonlydefaults[kwarg]\n', '            else:\n', '                missing += 1\n', '    if missing:\n', '        _missing_arguments(f_name, kwonlyargs, False, arg2value)\n', '    return arg2value\n', '\n', "ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')\n", '\n', 'def getclosurevars(func):\n', '    """\n', '    Get the mapping of free variables to their current values.\n', '\n', '    Returns a named tuple of dicts mapping the current nonlocal, global\n', '    and builtin references as seen by the body of the function. A final\n', '    set of unbound names that could not be resolved is also provided.\n', '    """\n', '\n', '    if ismethod(func):\n', '        func = func.__func__\n', '\n', '    if not isfunction(func):\n', '        raise TypeError("{!r} is not a Python function".format(func))\n', '\n', '    code = func.__code__\n', '    # Nonlocal references are named in co_freevars and resolved\n', '    # by looking them up in __closure__ by positional index\n', '    if func.__closure__ is None:\n', '        nonlocal_vars = {}\n', '    else:\n', '        nonlocal_vars = {\n', '            var : cell.cell_contents\n', '            for var, cell in zip(code.co_freevars, func.__closure__)\n', '       }\n', '\n', '    # Global and builtin references are named in co_names and resolved\n', '    # by looking them up in __globals__ or __builtins__\n', '    global_ns = func.__globals__\n', '    builtin_ns = global_ns.get("__builtins__", builtins.__dict__)\n', '    if ismodule(builtin_ns):\n', '        builtin_ns = builtin_ns.__dict__\n', '    global_vars = {}\n', '    builtin_vars = {}\n', '    unbound_names = set()\n', '    for name in code.co_names:\n', '        if name in ("None", "True", "False"):\n', '            # Because these used to be builtins instead of keywords, they\n', '            # may still show up as name references. We ignore them.\n', '            continue\n', '        try:\n', '            global_vars[name] = global_ns[name]\n', '        except KeyError:\n', '            try:\n', '                builtin_vars[name] = builtin_ns[name]\n', '            except KeyError:\n', '                unbound_names.add(name)\n', '\n', '    return ClosureVars(nonlocal_vars, global_vars,\n', '                       builtin_vars, unbound_names)\n', '\n', '# -------------------------------------------------- stack frame extraction\n', '\n', "Traceback = namedtuple('Traceback', 'filename lineno function code_context index')\n", '\n', 'def getframeinfo(frame, context=1):\n', '    """Get information about a frame or traceback object.\n', '\n', '    A tuple of five things is returned: the filename, the line number of\n', '    the current line, the function name, a list of lines of context from\n', '    the source code, and the index of the current line within that list.\n', '    The optional second argument specifies the number of lines of context\n', '    to return, which are centered around the current line."""\n', '    if istraceback(frame):\n', '        lineno = frame.tb_lineno\n', '        frame = frame.tb_frame\n', '    else:\n', '        lineno = frame.f_lineno\n', '    if not isframe(frame):\n', "        raise TypeError('{!r} is not a frame or traceback object'.format(frame))\n", '\n', '    filename = getsourcefile(frame) or getfile(frame)\n', '    if context > 0:\n', '        start = lineno - 1 - context//2\n', '        try:\n', '            lines, lnum = findsource(frame)\n', '        except OSError:\n', '            lines = index = None\n', '        else:\n', '            start = max(0, min(start, len(lines) - context))\n', '            lines = lines[start:start+context]\n', '            index = lineno - 1 - start\n', '    else:\n', '        lines = index = None\n', '\n', '    return Traceback(filename, lineno, frame.f_code.co_name, lines, index)\n', '\n', 'def getlineno(frame):\n', '    """Get the line number from a frame object, allowing for optimization."""\n', '    # FrameType.f_lineno is now a descriptor that grovels co_lnotab\n', '    return frame.f_lineno\n', '\n', "FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)\n", '\n', 'def getouterframes(frame, context=1):\n', '    """Get a list of records for a frame and all higher (calling) frames.\n', '\n', '    Each record contains a frame object, filename, line number, function\n', '    name, a list of lines of context, and index within the context."""\n', '    framelist = []\n', '    while frame:\n', '        frameinfo = (frame,) + getframeinfo(frame, context)\n', '        framelist.append(FrameInfo(*frameinfo))\n', '        frame = frame.f_back\n', '    return framelist\n', '\n', 'def getinnerframes(tb, context=1):\n', '    """Get a list of records for a traceback\'s frame and all lower frames.\n', '\n', '    Each record contains a frame object, filename, line number, function\n', '    name, a list of lines of context, and index within the context."""\n', '    framelist = []\n', '    while tb:\n', '        frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n', '        framelist.append(FrameInfo(*frameinfo))\n', '        tb = tb.tb_next\n', '    return framelist\n', '\n', 'def currentframe():\n', '    """Return the frame of the caller or None if this is not possible."""\n', '    return sys._getframe(1) if hasattr(sys, "_getframe") else None\n', '\n', 'def stack(context=1):\n', '    """Return a list of records for the stack above the caller\'s frame."""\n', '    return getouterframes(sys._getframe(1), context)\n', '\n', 'def trace(context=1):\n', '    """Return a list of records for the stack below the current exception."""\n', '    return getinnerframes(sys.exc_info()[2], context)\n', '\n', '\n', '# ------------------------------------------------ static version of getattr\n', '\n', '_sentinel = object()\n', '\n', 'def _static_getmro(klass):\n', "    return type.__dict__['__mro__'].__get__(klass)\n", '\n', 'def _check_instance(obj, attr):\n', '    instance_dict = {}\n', '    try:\n', '        instance_dict = object.__getattribute__(obj, "__dict__")\n', '    except AttributeError:\n', '        pass\n', '    return dict.get(instance_dict, attr, _sentinel)\n', '\n', '\n', 'def _check_class(klass, attr):\n', '    for entry in _static_getmro(klass):\n', '        if _shadowed_dict(type(entry)) is _sentinel:\n', '            try:\n', '                return entry.__dict__[attr]\n', '            except KeyError:\n', '                pass\n', '    return _sentinel\n', '\n', 'def _is_type(obj):\n', '    try:\n', '        _static_getmro(obj)\n', '    except TypeError:\n', '        return False\n', '    return True\n', '\n', 'def _shadowed_dict(klass):\n', '    dict_attr = type.__dict__["__dict__"]\n', '    for entry in _static_getmro(klass):\n', '        try:\n', '            class_dict = dict_attr.__get__(entry)["__dict__"]\n', '        except KeyError:\n', '            pass\n', '        else:\n', '            if not (type(class_dict) is types.GetSetDescriptorType and\n', '                    class_dict.__name__ == "__dict__" and\n', '                    class_dict.__objclass__ is entry):\n', '                return class_dict\n', '    return _sentinel\n', '\n', 'def getattr_static(obj, attr, default=_sentinel):\n', '    """Retrieve attributes without triggering dynamic lookup via the\n', '       descriptor protocol,  __getattr__ or __getattribute__.\n', '\n', '       Note: this function may not be able to retrieve all attributes\n', '       that getattr can fetch (like dynamically created attributes)\n', "       and may find attributes that getattr can't (like descriptors\n", '       that raise AttributeError). It can also return descriptor objects\n', '       instead of instance members in some cases. See the\n', '       documentation for details.\n', '    """\n', '    instance_result = _sentinel\n', '    if not _is_type(obj):\n', '        klass = type(obj)\n', '        dict_attr = _shadowed_dict(klass)\n', '        if (dict_attr is _sentinel or\n', '            type(dict_attr) is types.MemberDescriptorType):\n', '            instance_result = _check_instance(obj, attr)\n', '    else:\n', '        klass = obj\n', '\n', '    klass_result = _check_class(klass, attr)\n', '\n', '    if instance_result is not _sentinel and klass_result is not _sentinel:\n', "        if (_check_class(type(klass_result), '__get__') is not _sentinel and\n", "            _check_class(type(klass_result), '__set__') is not _sentinel):\n", '            return klass_result\n', '\n', '    if instance_result is not _sentinel:\n', '        return instance_result\n', '    if klass_result is not _sentinel:\n', '        return klass_result\n', '\n', '    if obj is klass:\n', '        # for types we check the metaclass too\n', '        for entry in _static_getmro(type(klass)):\n', '            if _shadowed_dict(type(entry)) is _sentinel:\n', '                try:\n', '                    return entry.__dict__[attr]\n', '                except KeyError:\n', '                    pass\n', '    if default is not _sentinel:\n', '        return default\n', '    raise AttributeError(attr)\n', '\n', '\n', '# ------------------------------------------------ generator introspection\n', '\n', "GEN_CREATED = 'GEN_CREATED'\n", "GEN_RUNNING = 'GEN_RUNNING'\n", "GEN_SUSPENDED = 'GEN_SUSPENDED'\n", "GEN_CLOSED = 'GEN_CLOSED'\n", '\n', 'def getgeneratorstate(generator):\n', '    """Get current state of a generator-iterator.\n', '\n', '    Possible states are:\n', '      GEN_CREATED: Waiting to start execution.\n', '      GEN_RUNNING: Currently being executed by the interpreter.\n', '      GEN_SUSPENDED: Currently suspended at a yield expression.\n', '      GEN_CLOSED: Execution has completed.\n', '    """\n', '    if generator.gi_running:\n', '        return GEN_RUNNING\n', '    if generator.gi_frame is None:\n', '        return GEN_CLOSED\n', '    if generator.gi_frame.f_lasti == -1:\n', '        return GEN_CREATED\n', '    return GEN_SUSPENDED\n', '\n', '\n', 'def getgeneratorlocals(generator):\n', '    """\n', '    Get the mapping of generator local variables to their current values.\n', '\n', '    A dict is returned, with the keys the local variable names and values the\n', '    bound values."""\n', '\n', '    if not isgenerator(generator):\n', '        raise TypeError("{!r} is not a Python generator".format(generator))\n', '\n', '    frame = getattr(generator, "gi_frame", None)\n', '    if frame is not None:\n', '        return generator.gi_frame.f_locals\n', '    else:\n', '        return {}\n', '\n', '\n', '# ------------------------------------------------ coroutine introspection\n', '\n', "CORO_CREATED = 'CORO_CREATED'\n", "CORO_RUNNING = 'CORO_RUNNING'\n", "CORO_SUSPENDED = 'CORO_SUSPENDED'\n", "CORO_CLOSED = 'CORO_CLOSED'\n", '\n', 'def getcoroutinestate(coroutine):\n', '    """Get current state of a coroutine object.\n', '\n', '    Possible states are:\n', '      CORO_CREATED: Waiting to start execution.\n', '      CORO_RUNNING: Currently being executed by the interpreter.\n', '      CORO_SUSPENDED: Currently suspended at an await expression.\n', '      CORO_CLOSED: Execution has completed.\n', '    """\n', '    if coroutine.cr_running:\n', '        return CORO_RUNNING\n', '    if coroutine.cr_frame is None:\n', '        return CORO_CLOSED\n', '    if coroutine.cr_frame.f_lasti == -1:\n', '        return CORO_CREATED\n', '    return CORO_SUSPENDED\n', '\n', '\n', 'def getcoroutinelocals(coroutine):\n', '    """\n', '    Get the mapping of coroutine local variables to their current values.\n', '\n', '    A dict is returned, with the keys the local variable names and values the\n', '    bound values."""\n', '    frame = getattr(coroutine, "cr_frame", None)\n', '    if frame is not None:\n', '        return frame.f_locals\n', '    else:\n', '        return {}\n', '\n', '\n', '###############################################################################\n', '### Function Signature Object (PEP 362)\n', '###############################################################################\n', '\n', '\n', '_WrapperDescriptor = type(type.__call__)\n', '_MethodWrapper = type(all.__call__)\n', "_ClassMethodWrapper = type(int.__dict__['from_bytes'])\n", '\n', '_NonUserDefinedCallables = (_WrapperDescriptor,\n', '                            _MethodWrapper,\n', '                            _ClassMethodWrapper,\n', '                            types.BuiltinFunctionType)\n', '\n', '\n', 'def _signature_get_user_defined_method(cls, method_name):\n', '    """Private helper. Checks if ``cls`` has an attribute\n', '    named ``method_name`` and returns it only if it is a\n', '    pure python function.\n', '    """\n', '    try:\n', '        meth = getattr(cls, method_name)\n', '    except AttributeError:\n', '        return\n', '    else:\n', '        if not isinstance(meth, _NonUserDefinedCallables):\n', "            # Once '__signature__' will be added to 'C'-level\n", "            # callables, this check won't be necessary\n", '            return meth\n', '\n', '\n', 'def _signature_get_partial(wrapped_sig, partial, extra_args=()):\n', '    """Private helper to calculate how \'wrapped_sig\' signature will\n', "    look like after applying a 'functools.partial' object (or alike)\n", '    on it.\n', '    """\n', '\n', '    old_params = wrapped_sig.parameters\n', '    new_params = OrderedDict(old_params.items())\n', '\n', '    partial_args = partial.args or ()\n', '    partial_keywords = partial.keywords or {}\n', '\n', '    if extra_args:\n', '        partial_args = extra_args + partial_args\n', '\n', '    try:\n', '        ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)\n', '    except TypeError as ex:\n', "        msg = 'partial object {!r} has incorrect arguments'.format(partial)\n", '        raise ValueError(msg) from ex\n', '\n', '\n', '    transform_to_kwonly = False\n', '    for param_name, param in old_params.items():\n', '        try:\n', '            arg_value = ba.arguments[param_name]\n', '        except KeyError:\n', '            pass\n', '        else:\n', '            if param.kind is _POSITIONAL_ONLY:\n', '                # If positional-only parameter is bound by partial,\n', '                # it effectively disappears from the signature\n', '                new_params.pop(param_name)\n', '                continue\n', '\n', '            if param.kind is _POSITIONAL_OR_KEYWORD:\n', '                if param_name in partial_keywords:\n', '                    # This means that this parameter, and all parameters\n', '                    # after it should be keyword-only (and var-positional\n', "                    # should be removed). Here's why. Consider the following\n", '                    # function:\n', '                    #     foo(a, b, *args, c):\n', '                    #         pass\n', '                    #\n', '                    # "partial(foo, a=\'spam\')" will have the following\n', '                    # signature: "(*, a=\'spam\', b, c)". Because attempting\n', '                    # to call that partial with "(10, 20)" arguments will\n', '                    # raise a TypeError, saying that "a" argument received\n', '                    # multiple values.\n', '                    transform_to_kwonly = True\n', '                    # Set the new default value\n', '                    new_params[param_name] = param.replace(default=arg_value)\n', '                else:\n', '                    # was passed as a positional argument\n', '                    new_params.pop(param.name)\n', '                    continue\n', '\n', '            if param.kind is _KEYWORD_ONLY:\n', '                # Set the new default value\n', '                new_params[param_name] = param.replace(default=arg_value)\n', '\n', '        if transform_to_kwonly:\n', '            assert param.kind is not _POSITIONAL_ONLY\n', '\n', '            if param.kind is _POSITIONAL_OR_KEYWORD:\n', '                new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)\n', '                new_params[param_name] = new_param\n', '                new_params.move_to_end(param_name)\n', '            elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):\n', '                new_params.move_to_end(param_name)\n', '            elif param.kind is _VAR_POSITIONAL:\n', '                new_params.pop(param.name)\n', '\n', '    return wrapped_sig.replace(parameters=new_params.values())\n', '\n', '\n', 'def _signature_bound_method(sig):\n', '    """Private helper to transform signatures for unbound\n', '    functions to bound methods.\n', '    """\n', '\n', '    params = tuple(sig.parameters.values())\n', '\n', '    if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):\n', "        raise ValueError('invalid method signature')\n", '\n', '    kind = params[0].kind\n', '    if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):\n', '        # Drop first parameter:\n', "        # '(p1, p2[, ...])' -> '(p2[, ...])'\n", '        params = params[1:]\n', '    else:\n', '        if kind is not _VAR_POSITIONAL:\n', '            # Unless we add a new parameter type we never\n', '            # get here\n', "            raise ValueError('invalid argument type')\n", "        # It's a var-positional parameter.\n", "        # Do nothing. '(*args[, ...])' -> '(*args[, ...])'\n", '\n', '    return sig.replace(parameters=params)\n', '\n', '\n', 'def _signature_is_builtin(obj):\n', '    """Private helper to test if `obj` is a callable that might\n', "    support Argument Clinic's __text_signature__ protocol.\n", '    """\n', '    return (isbuiltin(obj) or\n', '            ismethoddescriptor(obj) or\n', '            isinstance(obj, _NonUserDefinedCallables) or\n', "            # Can't test 'isinstance(type)' here, as it would\n", '            # also be True for regular python classes\n', '            obj in (type, object))\n', '\n', '\n', 'def _signature_is_functionlike(obj):\n', '    """Private helper to test if `obj` is a duck type of FunctionType.\n', '    A good example of such objects are functions compiled with\n', '    Cython, which have all attributes that a pure Python function\n', '    would have, but have their code statically compiled.\n', '    """\n', '\n', '    if not callable(obj) or isclass(obj):\n', '        # All function-like objects are obviously callables,\n', '        # and not classes.\n', '        return False\n', '\n', "    name = getattr(obj, '__name__', None)\n", "    code = getattr(obj, '__code__', None)\n", "    defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...\n", "    kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here\n", "    annotations = getattr(obj, '__annotations__', None)\n", '\n', '    return (isinstance(code, types.CodeType) and\n', '            isinstance(name, str) and\n', '            (defaults is None or isinstance(defaults, tuple)) and\n', '            (kwdefaults is None or isinstance(kwdefaults, dict)) and\n', '            (isinstance(annotations, (dict)) or annotations is None) )\n', '\n', '\n', 'def _signature_get_bound_param(spec):\n', '    """ Private helper to get first parameter name from a\n', '    __text_signature__ of a builtin method, which should\n', "    be in the following format: '($param1, ...)'.\n", "    Assumptions are that the first argument won't have\n", '    a default value or an annotation.\n', '    """\n', '\n', "    assert spec.startswith('(


)\n", '\n', "    pos = spec.find(',')\n", '    if pos == -1:\n', "        pos = spec.find(')')\n", '\n', "    cpos = spec.find(':')\n", '    assert cpos == -1 or cpos > pos\n', '\n', "    cpos = spec.find('=')\n", '    assert cpos == -1 or cpos > pos\n', '\n', '    return spec[2:pos]\n', '\n', '\n', 'def _signature_strip_non_python_syntax(signature):\n', '    """\n', "    Private helper function. Takes a signature in Argument Clinic's\n", '    extended signature format.\n', '\n', '    Returns a tuple of three things:\n', '      * that signature re-rendered in standard Python syntax,\n', '      * the index of the "self" parameter (generally 0), or None if\n', '        the function does not have a "self" parameter, and\n', '      * the index of the last "positional only" parameter,\n', '        or None if the signature has no positional-only parameters.\n', '    """\n', '\n', '    if not signature:\n', '        return signature, None, None\n', '\n', '    self_parameter = None\n', '    last_positional_only = None\n', '\n', "    lines = [l.encode('ascii') for l in signature.split('\\n')]\n", '    generator = iter(lines).__next__\n', '    token_stream = tokenize.tokenize(generator)\n', '\n', '    delayed_comma = False\n', '    skip_next_comma = False\n', '    text = []\n', '    add = text.append\n', '\n', '    current_parameter = 0\n', '    OP = token.OP\n', '    ERRORTOKEN = token.ERRORTOKEN\n', '\n', '    # token stream always starts with ENCODING token, skip it\n', '    t = next(token_stream)\n', '    assert t.type == tokenize.ENCODING\n', '\n', '    for t in token_stream:\n', '        type, string = t.type, t.string\n', '\n', '        if type == OP:\n', "            if string == ',':\n", '                if skip_next_comma:\n', '                    skip_next_comma = False\n', '                else:\n', '                    assert not delayed_comma\n', '                    delayed_comma = True\n', '                    current_parameter += 1\n', '                continue\n', '\n', "            if string == '/':\n", '                assert not skip_next_comma\n', '                assert last_positional_only is None\n', '                skip_next_comma = True\n', '                last_positional_only = current_parameter - 1\n', '                continue\n', '\n', "        if (type == ERRORTOKEN) and (string == '


):\n", '            assert self_parameter is None\n', '            self_parameter = current_parameter\n', '            continue\n', '\n', '        if delayed_comma:\n', '            delayed_comma = False\n', "            if not ((type == OP) and (string == ')')):\n", "                add(', ')\n", '        add(string)\n', "        if (string == ','):\n", "            add(' ')\n", "    clean_signature = ''.join(text)\n", '    return clean_signature, self_parameter, last_positional_only\n', '\n', '\n', 'def _signature_fromstr(cls, obj, s, skip_bound_arg=True):\n', '    """Private helper to parse content of \'__text_signature__\'\n', '    and return a Signature based on it.\n', '    """\n', "    # Lazy import ast because it's relatively heavy and\n", "    # it's not used for other than this function.\n", '    import ast\n', '\n', '    Parameter = cls._parameter_cls\n', '\n', '    clean_signature, self_parameter, last_positional_only = \\\n', '        _signature_strip_non_python_syntax(s)\n', '\n', '    program = "def foo" + clean_signature + ": pass"\n', '\n', '    try:\n', '        module = ast.parse(program)\n', '    except SyntaxError:\n', '        module = None\n', '\n', '    if not isinstance(module, ast.Module):\n', '        raise ValueError("{!r} builtin has invalid signature".format(obj))\n', '\n', '    f = module.body[0]\n', '\n', '    parameters = []\n', '    empty = Parameter.empty\n', '    invalid = object()\n', '\n', '    module = None\n', '    module_dict = {}\n', "    module_name = getattr(obj, '__module__', None)\n", '    if module_name:\n', '        module = sys.modules.get(module_name, None)\n', '        if module:\n', '            module_dict = module.__dict__\n', '    sys_module_dict = sys.modules.copy()\n', '\n', '    def parse_name(node):\n', '        assert isinstance(node, ast.arg)\n', '        if node.annotation is not None:\n', '            raise ValueError("Annotations are not currently supported")\n', '        return node.arg\n', '\n', '    def wrap_value(s):\n', '        try:\n', '            value = eval(s, module_dict)\n', '        except NameError:\n', '            try:\n', '                value = eval(s, sys_module_dict)\n', '            except NameError:\n', '                raise RuntimeError()\n', '\n', '        if isinstance(value, (str, int, float, bytes, bool, type(None))):\n', '            return ast.Constant(value)\n', '        raise RuntimeError()\n', '\n', '    class RewriteSymbolics(ast.NodeTransformer):\n', '        def visit_Attribute(self, node):\n', '            a = []\n', '            n = node\n', '            while isinstance(n, ast.Attribute):\n', '                a.append(n.attr)\n', '                n = n.value\n', '            if not isinstance(n, ast.Name):\n', '                raise RuntimeError()\n', '            a.append(n.id)\n', '            value = ".".join(reversed(a))\n', '            return wrap_value(value)\n', '\n', '        def visit_Name(self, node):\n', '            if not isinstance(node.ctx, ast.Load):\n', '                raise ValueError()\n', '            return wrap_value(node.id)\n', '\n', '    def p(name_node, default_node, default=empty):\n', '        name = parse_name(name_node)\n', '        if name is invalid:\n', '            return None\n', '        if default_node and default_node is not _empty:\n', '            try:\n', '                default_node = RewriteSymbolics().visit(default_node)\n', '                o = ast.literal_eval(default_node)\n', '            except ValueError:\n', '                o = invalid\n', '            if o is invalid:\n', '                return None\n', '            default = o if o is not invalid else default\n', '        parameters.append(Parameter(name, kind, default=default, annotation=empty))\n', '\n', '    # non-keyword-only parameters\n', '    args = reversed(f.args.args)\n', '    defaults = reversed(f.args.defaults)\n', '    iter = itertools.zip_longest(args, defaults, fillvalue=None)\n', '    if last_positional_only is not None:\n', '        kind = Parameter.POSITIONAL_ONLY\n', '    else:\n', '        kind = Parameter.POSITIONAL_OR_KEYWORD\n', '    for i, (name, default) in enumerate(reversed(list(iter))):\n', '        p(name, default)\n', '        if i == last_positional_only:\n', '            kind = Parameter.POSITIONAL_OR_KEYWORD\n', '\n', '    # *args\n', '    if f.args.vararg:\n', '        kind = Parameter.VAR_POSITIONAL\n', '        p(f.args.vararg, empty)\n', '\n', '    # keyword-only arguments\n', '    kind = Parameter.KEYWORD_ONLY\n', '    for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):\n', '        p(name, default)\n', '\n', '    # **kwargs\n', '    if f.args.kwarg:\n', '        kind = Parameter.VAR_KEYWORD\n', '        p(f.args.kwarg, empty)\n', '\n', '    if self_parameter is not None:\n', '        # Possibly strip the bound argument:\n', '        #    - We *always* strip first bound argument if\n', '        #      it is a module.\n', "        #    - We don't strip first bound argument if\n", '        #      skip_bound_arg is False.\n', '        assert parameters\n', "        _self = getattr(obj, '__self__', None)\n", '        self_isbound = _self is not None\n', '        self_ismodule = ismodule(_self)\n', '        if self_isbound and (self_ismodule or skip_bound_arg):\n', '            parameters.pop(0)\n', '        else:\n', '            # for builtins, self parameter is always positional-only!\n', '            p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)\n', '            parameters[0] = p\n', '\n', '    return cls(parameters, return_annotation=cls.empty)\n', '\n', '\n', 'def _signature_from_builtin(cls, func, skip_bound_arg=True):\n', '    """Private helper function to get signature for\n', '    builtin callables.\n', '    """\n', '\n', '    if not _signature_is_builtin(func):\n', '        raise TypeError("{!r} is not a Python builtin "\n', '                        "function".format(func))\n', '\n', '    s = getattr(func, "__text_signature__", None)\n', '    if not s:\n', '        raise ValueError("no signature found for builtin {!r}".format(func))\n', '\n', '    return _signature_fromstr(cls, func, s, skip_bound_arg)\n', '\n', '\n', 'def _signature_from_function(cls, func, skip_bound_arg=True,\n', '                             globals=None, locals=None, eval_str=False):\n', '    """Private helper: constructs Signature for the given python function."""\n', '\n', '    is_duck_function = False\n', '    if not isfunction(func):\n', '        if _signature_is_functionlike(func):\n', '            is_duck_function = True\n', '        else:\n', "            # If it's not a pure Python function, and not a duck type\n", '            # of pure function:\n', "            raise TypeError('{!r} is not a Python function'.format(func))\n", '\n', '    s = getattr(func, "__text_signature__", None)\n', '    if s:\n', '        return _signature_fromstr(cls, func, s, skip_bound_arg)\n', '\n', '    Parameter = cls._parameter_cls\n', '\n', '    # Parameter information.\n', '    func_code = func.__code__\n', '    pos_count = func_code.co_argcount\n', '    arg_names = func_code.co_varnames\n', '    posonly_count = func_code.co_posonlyargcount\n', '    positional = arg_names[:pos_count]\n', '    keyword_only_count = func_code.co_kwonlyargcount\n', '    keyword_only = arg_names[pos_count:pos_count + keyword_only_count]\n', '    annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str)\n', '    defaults = func.__defaults__\n', '    kwdefaults = func.__kwdefaults__\n', '\n', '    if defaults:\n', '        pos_default_count = len(defaults)\n', '    else:\n', '        pos_default_count = 0\n', '\n', '    parameters = []\n', '\n', '    non_default_count = pos_count - pos_default_count\n', '    posonly_left = posonly_count\n', '\n', '    # Non-keyword-only parameters w/o defaults.\n', '    for name in positional[:non_default_count]:\n', '        kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD\n', '        annotation = annotations.get(name, _empty)\n', '        parameters.append(Parameter(name, annotation=annotation,\n', '                                    kind=kind))\n', '        if posonly_left:\n', '            posonly_left -= 1\n', '\n', '    # ... w/ defaults.\n', '    for offset, name in enumerate(positional[non_default_count:]):\n', '        kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD\n', '        annotation = annotations.get(name, _empty)\n', '        parameters.append(Parameter(name, annotation=annotation,\n', '                                    kind=kind,\n', '                                    default=defaults[offset]))\n', '        if posonly_left:\n', '            posonly_left -= 1\n', '\n', '    # *args\n', '    if func_code.co_flags & CO_VARARGS:\n', '        name = arg_names[pos_count + keyword_only_count]\n', '        annotation = annotations.get(name, _empty)\n', '        parameters.append(Parameter(name, annotation=annotation,\n', '                                    kind=_VAR_POSITIONAL))\n', '\n', '    # Keyword-only parameters.\n', '    for name in keyword_only:\n', '        default = _empty\n', '        if kwdefaults is not None:\n', '            default = kwdefaults.get(name, _empty)\n', '\n', '        annotation = annotations.get(name, _empty)\n', '        parameters.append(Parameter(name, annotation=annotation,\n', '                                    kind=_KEYWORD_ONLY,\n', '                                    default=default))\n', '    # **kwargs\n', '    if func_code.co_flags & CO_VARKEYWORDS:\n', '        index = pos_count + keyword_only_count\n', '        if func_code.co_flags & CO_VARARGS:\n', '            index += 1\n', '\n', '        name = arg_names[index]\n', '        annotation = annotations.get(name, _empty)\n', '        parameters.append(Parameter(name, annotation=annotation,\n', '                                    kind=_VAR_KEYWORD))\n', '\n', "    # Is 'func' is a pure Python function - don't validate the\n", '    # parameters list (for correct order and defaults), it should be OK.\n', '    return cls(parameters,\n', "               return_annotation=annotations.get('return', _empty),\n", '               __validate_parameters__=is_duck_function)\n', '\n', '\n', 'def _signature_from_callable(obj, *,\n', '                             follow_wrapper_chains=True,\n', '                             skip_bound_arg=True,\n', '                             globals=None,\n', '                             locals=None,\n', '                             eval_str=False,\n', '                             sigcls):\n', '\n', '    """Private helper function to get signature for arbitrary\n', '    callable objects.\n', '    """\n', '\n', '    _get_signature_of = functools.partial(_signature_from_callable,\n', '                                follow_wrapper_chains=follow_wrapper_chains,\n', '                                skip_bound_arg=skip_bound_arg,\n', '                                globals=globals,\n', '                                locals=locals,\n', '                                sigcls=sigcls,\n', '                                eval_str=eval_str)\n', '\n', '    if not callable(obj):\n', "        raise TypeError('{!r} is not a callable object'.format(obj))\n", '\n', '    if isinstance(obj, types.MethodType):\n', '        # In this case we skip the first parameter of the underlying\n', '        # function (usually `self` or `cls`).\n', '        sig = _get_signature_of(obj.__func__)\n', '\n', '        if skip_bound_arg:\n', '            return _signature_bound_method(sig)\n', '        else:\n', '            return sig\n', '\n', '    # Was this function wrapped by a decorator?\n', '    if follow_wrapper_chains:\n', '        obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))\n', '        if isinstance(obj, types.MethodType):\n', '            # If the unwrapped object is a *method*, we might want to\n', '            # skip its first parameter (self).\n', '            # See test_signature_wrapped_bound_method for details.\n', '            return _get_signature_of(obj)\n', '\n', '    try:\n', '        sig = obj.__signature__\n', '    except AttributeError:\n', '        pass\n', '    else:\n', '        if sig is not None:\n', '            if not isinstance(sig, Signature):\n', '                raise TypeError(\n', "                    'unexpected object {!r} in __signature__ '\n", "                    'attribute'.format(sig))\n", '            return sig\n', '\n', '    try:\n', '        partialmethod = obj._partialmethod\n', '    except AttributeError:\n', '        pass\n', '    else:\n', '        if isinstance(partialmethod, functools.partialmethod):\n', '            # Unbound partialmethod (see functools.partialmethod)\n', '            # This means, that we need to calculate the signature\n', "            # as if it's a regular partial object, but taking into\n", '            # account that the first positional argument\n', '            # (usually `self`, or `cls`) will not be passed\n', '            # automatically (as for boundmethods)\n', '\n', '            wrapped_sig = _get_signature_of(partialmethod.func)\n', '\n', '            sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))\n', '            first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]\n', '            if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:\n', '                # First argument of the wrapped callable is `*args`, as in\n', '                # `partialmethod(lambda *args)`.\n', '                return sig\n', '            else:\n', '                sig_params = tuple(sig.parameters.values())\n', '                assert (not sig_params or\n', '                        first_wrapped_param is not sig_params[0])\n', '                new_params = (first_wrapped_param,) + sig_params\n', '                return sig.replace(parameters=new_params)\n', '\n', '    if isfunction(obj) or _signature_is_functionlike(obj):\n', "        # If it's a pure Python function, or an object that is duck type\n", '        # of a Python function (Cython functions, for instance), then:\n', '        return _signature_from_function(sigcls, obj,\n', '                                        skip_bound_arg=skip_bound_arg,\n', '                                        globals=globals, locals=locals, eval_str=eval_str)\n', '\n', '    if _signature_is_builtin(obj):\n', '        return _signature_from_builtin(sigcls, obj,\n', '                                       skip_bound_arg=skip_bound_arg)\n', '\n', '    if isinstance(obj, functools.partial):\n', '        wrapped_sig = _get_signature_of(obj.func)\n', '        return _signature_get_partial(wrapped_sig, obj)\n', '\n', '    sig = None\n', '    if isinstance(obj, type):\n', '        # obj is a class or a metaclass\n', '\n', "        # First, let's see if it has an overloaded __call__ defined\n", '        # in its metaclass\n', "        call = _signature_get_user_defined_method(type(obj), '__call__')\n", '        if call is not None:\n', '            sig = _get_signature_of(call)\n', '        else:\n', '            factory_method = None\n', "            new = _signature_get_user_defined_method(obj, '__new__')\n", "            init = _signature_get_user_defined_method(obj, '__init__')\n", "            # Now we check if the 'obj' class has an own '__new__' method\n", "            if '__new__' in obj.__dict__:\n", '                factory_method = new\n', "            # or an own '__init__' method\n", "            elif '__init__' in obj.__dict__:\n", '                factory_method = init\n', "            # If not, we take inherited '__new__' or '__init__', if present\n", '            elif new is not None:\n', '                factory_method = new\n', '            elif init is not None:\n', '                factory_method = init\n', '\n', '            if factory_method is not None:\n', '                sig = _get_signature_of(factory_method)\n', '\n', '        if sig is None:\n', '            # At this point we know, that `obj` is a class, with no user-\n', "            # defined '__init__', '__new__', or class-level '__call__'\n", '\n', '            for base in obj.__mro__[:-1]:\n', "                # Since '__text_signature__' is implemented as a\n", '                # descriptor that extracts text signature from the\n', "                # class docstring, if 'obj' is derived from a builtin\n", "                # class, its own '__text_signature__' may be 'None'.\n", '                # Therefore, we go through the MRO (except the last\n', "                # class in there, which is 'object') to find the first\n", '                # class with non-empty text signature.\n', '                try:\n', '                    text_sig = base.__text_signature__\n', '                except AttributeError:\n', '                    pass\n', '                else:\n', '                    if text_sig:\n', "                        # If 'base' class has a __text_signature__ attribute:\n", '                        # return a signature based on it\n', '                        return _signature_fromstr(sigcls, base, text_sig)\n', '\n', "            # No '__text_signature__' was found for the 'obj' class.\n", "            # Last option is to check if its '__init__' is\n", '            # object.__init__ or type.__init__.\n', '            if type not in obj.__mro__:\n', '                # We have a class (not metaclass), but no user-defined\n', '                # __init__ or __new__ for it\n', '                if (obj.__init__ is object.__init__ and\n', '                    obj.__new__ is object.__new__):\n', "                    # Return a signature of 'object' builtin.\n", '                    return sigcls.from_callable(object)\n', '                else:\n', '                    raise ValueError(\n', "                        'no signature found for builtin type {!r}'.format(obj))\n", '\n', '    elif not isinstance(obj, _NonUserDefinedCallables):\n', '        # An object with __call__\n', "        # We also check that the 'obj' is not an instance of\n", '        # _WrapperDescriptor or _MethodWrapper to avoid\n', '        # infinite recursion (and even potential segfault)\n', "        call = _signature_get_user_defined_method(type(obj), '__call__')\n", '        if call is not None:\n', '            try:\n', '                sig = _get_signature_of(call)\n', '            except ValueError as ex:\n', "                msg = 'no signature found for {!r}'.format(obj)\n", '                raise ValueError(msg) from ex\n', '\n', '    if sig is not None:\n', '        # For classes and objects we skip the first parameter of their\n', '        # __call__, __new__, or __init__ methods\n', '        if skip_bound_arg:\n', '            return _signature_bound_method(sig)\n', '        else:\n', '            return sig\n', '\n', '    if isinstance(obj, types.BuiltinFunctionType):\n', '        # Raise a nicer error message for builtins\n', "        msg = 'no signature found for builtin function {!r}'.format(obj)\n", '        raise ValueError(msg)\n', '\n', "    raise ValueError('callable {!r} is not supported by signature'.format(obj))\n", '\n', '\n', 'class _void:\n', '    """A private marker - used in Parameter & Signature."""\n', '\n', '\n', 'class _empty:\n', '    """Marker object for Signature.empty and Parameter.empty."""\n', '\n', '\n', 'class _ParameterKind(enum.IntEnum):\n', '    POSITIONAL_ONLY = 0\n', '    POSITIONAL_OR_KEYWORD = 1\n', '    VAR_POSITIONAL = 2\n', '    KEYWORD_ONLY = 3\n', '    VAR_KEYWORD = 4\n', '\n', '    def __str__(self):\n', '        return self._name_\n', '\n', '    @property\n', '    def description(self):\n', '        return _PARAM_NAME_MAPPING[self]\n', '\n', '_POSITIONAL_ONLY         = _ParameterKind.POSITIONAL_ONLY\n', '_POSITIONAL_OR_KEYWORD   = _ParameterKind.POSITIONAL_OR_KEYWORD\n', '_VAR_POSITIONAL          = _ParameterKind.VAR_POSITIONAL\n', '_KEYWORD_ONLY            = _ParameterKind.KEYWORD_ONLY\n', '_VAR_KEYWORD             = _ParameterKind.VAR_KEYWORD\n', '\n', '_PARAM_NAME_MAPPING = {\n', "    _POSITIONAL_ONLY: 'positional-only',\n", "    _POSITIONAL_OR_KEYWORD: 'positional or keyword',\n", "    _VAR_POSITIONAL: 'variadic positional',\n", "    _KEYWORD_ONLY: 'keyword-only',\n", "    _VAR_KEYWORD: 'variadic keyword'\n", '}\n', '\n', '\n', 'class Parameter:\n', '    """Represents a parameter in a function signature.\n', '\n', '    Has the following public attributes:\n', '\n', '    * name : str\n', '        The name of the parameter as a string.\n', '    * default : object\n', '        The default value for the parameter if specified.  If the\n', '        parameter has no default value, this attribute is set to\n', '        `Parameter.empty`.\n', '    * annotation\n', '        The annotation for the parameter if specified.  If the\n', '        parameter has no annotation, this attribute is set to\n', '        `Parameter.empty`.\n', '    * kind : str\n', '        Describes how argument values are bound to the parameter.\n', '        Possible values: `Parameter.POSITIONAL_ONLY`,\n', '        `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,\n', '        `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.\n', '    """\n', '\n', "    __slots__ = ('_name', '_kind', '_default', '_annotation')\n", '\n', '    POSITIONAL_ONLY         = _POSITIONAL_ONLY\n', '    POSITIONAL_OR_KEYWORD   = _POSITIONAL_OR_KEYWORD\n', '    VAR_POSITIONAL          = _VAR_POSITIONAL\n', '    KEYWORD_ONLY            = _KEYWORD_ONLY\n', '    VAR_KEYWORD             = _VAR_KEYWORD\n', '\n', '    empty = _empty\n', '\n', '    def __init__(self, name, kind, *, default=_empty, annotation=_empty):\n', '        try:\n', '            self._kind = _ParameterKind(kind)\n', '        except ValueError:\n', "            raise ValueError(f'value {kind!r} is not a valid Parameter.kind')\n", '        if default is not _empty:\n', '            if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):\n', "                msg = '{} parameters cannot have default values'\n", '                msg = msg.format(self._kind.description)\n', '                raise ValueError(msg)\n', '        self._default = default\n', '        self._annotation = annotation\n', '\n', '        if name is _empty:\n', "            raise ValueError('name is a required attribute for Parameter')\n", '\n', '        if not isinstance(name, str):\n', "            msg = 'name must be a str, not a {}'.format(type(name).__name__)\n", '            raise TypeError(msg)\n', '\n', "        if name[0] == '.' and name[1:].isdigit():\n", '            # These are implicit arguments generated by comprehensions. In\n', '            # order to provide a friendlier interface to users, we recast\n', '            # their name as "implicitN" and treat them as positional-only.\n', '            # See issue 19611.\n', '            if self._kind != _POSITIONAL_OR_KEYWORD:\n', '                msg = (\n', "                    'implicit arguments must be passed as '\n", "                    'positional or keyword arguments, not {}'\n", '                )\n', '                msg = msg.format(self._kind.description)\n', '                raise ValueError(msg)\n', '            self._kind = _POSITIONAL_ONLY\n', "            name = 'implicit{}'.format(name[1:])\n", '\n', '        if not name.isidentifier():\n', "            raise ValueError('{!r} is not a valid parameter name'.format(name))\n", '\n', '        self._name = name\n', '\n', '    def __reduce__(self):\n', '        return (type(self),\n', '                (self._name, self._kind),\n', "                {'_default': self._default,\n", "                 '_annotation': self._annotation})\n", '\n', '    def __setstate__(self, state):\n', "        self._default = state['_default']\n", "        self._annotation = state['_annotation']\n", '\n', '    @property\n', '    def name(self):\n', '        return self._name\n', '\n', '    @property\n', '    def default(self):\n', '        return self._default\n', '\n', '    @property\n', '    def annotation(self):\n', '        return self._annotation\n', '\n', '    @property\n', '    def kind(self):\n', '        return self._kind\n', '\n', '    def replace(self, *, name=_void, kind=_void,\n', '                annotation=_void, default=_void):\n', '        """Creates a customized copy of the Parameter."""\n', '\n', '        if name is _void:\n', '            name = self._name\n', '\n', '        if kind is _void:\n', '            kind = self._kind\n', '\n', '        if annotation is _void:\n', '            annotation = self._annotation\n', '\n', '        if default is _void:\n', '            default = self._default\n', '\n', '        return type(self)(name, kind, default=default, annotation=annotation)\n', '\n', '    def __str__(self):\n', '        kind = self.kind\n', '        formatted = self._name\n', '\n', '        # Add annotation and default value\n', '        if self._annotation is not _empty:\n', "            formatted = '{}: {}'.format(formatted,\n", '                                       formatannotation(self._annotation))\n', '\n', '        if self._default is not _empty:\n', '            if self._annotation is not _empty:\n', "                formatted = '{} = {}'.format(formatted, repr(self._default))\n", '            else:\n', "                formatted = '{}={}'.format(formatted, repr(self._default))\n", '\n', '        if kind == _VAR_POSITIONAL:\n', "            formatted = '*' + formatted\n", '        elif kind == _VAR_KEYWORD:\n', "            formatted = '**' + formatted\n", '\n', '        return formatted\n', '\n', '    def __repr__(self):\n', '        return \'<{} "{}">\'.format(self.__class__.__name__, self)\n', '\n', '    def __hash__(self):\n', '        return hash((self.name, self.kind, self.annotation, self.default))\n', '\n', '    def __eq__(self, other):\n', '        if self is other:\n', '            return True\n', '        if not isinstance(other, Parameter):\n', '            return NotImplemented\n', '        return (self._name == other._name and\n', '                self._kind == other._kind and\n', '                self._default == other._default and\n', '                self._annotation == other._annotation)\n', '\n', '\n', 'class BoundArguments:\n', '    """Result of `Signature.bind` call.  Holds the mapping of arguments\n', "    to the function's parameters.\n", '\n', '    Has the following public attributes:\n', '\n', '    * arguments : dict\n', "        An ordered mutable mapping of parameters' names to arguments' values.\n", "        Does not contain arguments' default values.\n", '    * signature : Signature\n', '        The Signature object that created this instance.\n', '    * args : tuple\n', '        Tuple of positional arguments values.\n', '    * kwargs : dict\n', '        Dict of keyword arguments values.\n', '    """\n', '\n', "    __slots__ = ('arguments', '_signature', '__weakref__')\n", '\n', '    def __init__(self, signature, arguments):\n', '        self.arguments = arguments\n', '        self._signature = signature\n', '\n', '    @property\n', '    def signature(self):\n', '        return self._signature\n', '\n', '    @property\n', '    def args(self):\n', '        args = []\n', '        for param_name, param in self._signature.parameters.items():\n', '            if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):\n', '                break\n', '\n', '            try:\n', '                arg = self.arguments[param_name]\n', '            except KeyError:\n', "                # We're done here. Other arguments\n", "                # will be mapped in 'BoundArguments.kwargs'\n", '                break\n', '            else:\n', '                if param.kind == _VAR_POSITIONAL:\n', '                    # *args\n', '                    args.extend(arg)\n', '                else:\n', '                    # plain argument\n', '                    args.append(arg)\n', '\n', '        return tuple(args)\n', '\n', '    @property\n', '    def kwargs(self):\n', '        kwargs = {}\n', '        kwargs_started = False\n', '        for param_name, param in self._signature.parameters.items():\n', '            if not kwargs_started:\n', '                if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):\n', '                    kwargs_started = True\n', '                else:\n', '                    if param_name not in self.arguments:\n', '                        kwargs_started = True\n', '                        continue\n', '\n', '            if not kwargs_started:\n', '                continue\n', '\n', '            try:\n', '                arg = self.arguments[param_name]\n', '            except KeyError:\n', '                pass\n', '            else:\n', '                if param.kind == _VAR_KEYWORD:\n', '                    # **kwargs\n', '                    kwargs.update(arg)\n', '                else:\n', '                    # plain keyword argument\n', '                    kwargs[param_name] = arg\n', '\n', '        return kwargs\n', '\n', '    def apply_defaults(self):\n', '        """Set default values for missing arguments.\n', '\n', '        For variable-positional arguments (*args) the default is an\n', '        empty tuple.\n', '\n', '        For variable-keyword arguments (**kwargs) the default is an\n', '        empty dict.\n', '        """\n', '        arguments = self.arguments\n', '        new_arguments = []\n', '        for name, param in self._signature.parameters.items():\n', '            try:\n', '                new_arguments.append((name, arguments[name]))\n', '            except KeyError:\n', '                if param.default is not _empty:\n', '                    val = param.default\n', '                elif param.kind is _VAR_POSITIONAL:\n', '                    val = ()\n', '                elif param.kind is _VAR_KEYWORD:\n', '                    val = {}\n', '                else:\n', '                    # This BoundArguments was likely produced by\n', '                    # Signature.bind_partial().\n', '                    continue\n', '                new_arguments.append((name, val))\n', '        self.arguments = dict(new_arguments)\n', '\n', '    def __eq__(self, other):\n', '        if self is other:\n', '            return True\n', '        if not isinstance(other, BoundArguments):\n', '            return NotImplemented\n', '        return (self.signature == other.signature and\n', '                self.arguments == other.arguments)\n', '\n', '    def __setstate__(self, state):\n', "        self._signature = state['_signature']\n", "        self.arguments = state['arguments']\n", '\n', '    def __getstate__(self):\n', "        return {'_signature': self._signature, 'arguments': self.arguments}\n", '\n', '    def __repr__(self):\n', '        args = []\n', '        for arg, value in self.arguments.items():\n', "            args.append('{}={!r}'.format(arg, value))\n", "        return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))\n", '\n', '\n', 'class Signature:\n', '    """A Signature object represents the overall signature of a function.\n', '    It stores a Parameter object for each parameter accepted by the\n', '    function, as well as information specific to the function itself.\n', '\n', '    A Signature object has the following public attributes and methods:\n', '\n', '    * parameters : OrderedDict\n', "        An ordered mapping of parameters' names to the corresponding\n", '        Parameter objects (keyword-only arguments are in the same order\n', '        as listed in `code.co_varnames`).\n', '    * return_annotation : object\n', '        The annotation for the return type of the function if specified.\n', '        If the function has no annotation for its return type, this\n', '        attribute is set to `Signature.empty`.\n', '    * bind(*args, **kwargs) -> BoundArguments\n', '        Creates a mapping from positional and keyword arguments to\n', '        parameters.\n', '    * bind_partial(*args, **kwargs) -> BoundArguments\n', '        Creates a partial mapping from positional and keyword arguments\n', "        to parameters (simulating 'functools.partial' behavior.)\n", '    """\n', '\n', "    __slots__ = ('_return_annotation', '_parameters')\n", '\n', '    _parameter_cls = Parameter\n', '    _bound_arguments_cls = BoundArguments\n', '\n', '    empty = _empty\n', '\n', '    def __init__(self, parameters=None, *, return_annotation=_empty,\n', '                 __validate_parameters__=True):\n', '        """Constructs Signature from the given list of Parameter\n', "        objects and 'return_annotation'.  All arguments are optional.\n", '        """\n', '\n', '        if parameters is None:\n', '            params = OrderedDict()\n', '        else:\n', '            if __validate_parameters__:\n', '                params = OrderedDict()\n', '                top_kind = _POSITIONAL_ONLY\n', '                kind_defaults = False\n', '\n', '                for param in parameters:\n', '                    kind = param.kind\n', '                    name = param.name\n', '\n', '                    if kind < top_kind:\n', '                        msg = (\n', "                            'wrong parameter order: {} parameter before {} '\n", "                            'parameter'\n", '                        )\n', '                        msg = msg.format(top_kind.description,\n', '                                         kind.description)\n', '                        raise ValueError(msg)\n', '                    elif kind > top_kind:\n', '                        kind_defaults = False\n', '                        top_kind = kind\n', '\n', '                    if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):\n', '                        if param.default is _empty:\n', '                            if kind_defaults:\n', '                                # No default for this parameter, but the\n', '                                # previous parameter of the same kind had\n', '                                # a default\n', "                                msg = 'non-default argument follows default ' \\\n", "                                      'argument'\n", '                                raise ValueError(msg)\n', '                        else:\n', '                            # There is a default for this parameter.\n', '                            kind_defaults = True\n', '\n', '                    if name in params:\n', "                        msg = 'duplicate parameter name: {!r}'.format(name)\n", '                        raise ValueError(msg)\n', '\n', '                    params[name] = param\n', '            else:\n', '                params = OrderedDict((param.name, param) for param in parameters)\n', '\n', '        self._parameters = types.MappingProxyType(params)\n', '        self._return_annotation = return_annotation\n', '\n', '    @classmethod\n', '    def from_function(cls, func):\n', '        """Constructs Signature for the given python function.\n', '\n', '        Deprecated since Python 3.5, use `Signature.from_callable()`.\n', '        """\n', '\n', '        warnings.warn("inspect.Signature.from_function() is deprecated since "\n', '                      "Python 3.5, use Signature.from_callable()",\n', '                      DeprecationWarning, stacklevel=2)\n', '        return _signature_from_function(cls, func)\n', '\n', '    @classmethod\n', '    def from_builtin(cls, func):\n', '        """Constructs Signature for the given builtin function.\n', '\n', '        Deprecated since Python 3.5, use `Signature.from_callable()`.\n', '        """\n', '\n', '        warnings.warn("inspect.Signature.from_builtin() is deprecated since "\n', '                      "Python 3.5, use Signature.from_callable()",\n', '                      DeprecationWarning, stacklevel=2)\n', '        return _signature_from_builtin(cls, func)\n', '\n', '    @classmethod\n', '    def from_callable(cls, obj, *,\n', '                      follow_wrapped=True, globals=None, locals=None, eval_str=False):\n', '        """Constructs Signature for the given callable object."""\n', '        return _signature_from_callable(obj, sigcls=cls,\n', '                                        follow_wrapper_chains=follow_wrapped,\n', '                                        globals=globals, locals=locals, eval_str=eval_str)\n', '\n', '    @property\n', '    def parameters(self):\n', '        return self._parameters\n', '\n', '    @property\n', '    def return_annotation(self):\n', '        return self._return_annotation\n', '\n', '    def replace(self, *, parameters=_void, return_annotation=_void):\n', '        """Creates a customized copy of the Signature.\n', "        Pass 'parameters' and/or 'return_annotation' arguments\n", '        to override them in the new copy.\n', '        """\n', '\n', '        if parameters is _void:\n', '            parameters = self.parameters.values()\n', '\n', '        if return_annotation is _void:\n', '            return_annotation = self._return_annotation\n', '\n', '        return type(self)(parameters,\n', '                          return_annotation=return_annotation)\n', '\n', '    def _hash_basis(self):\n', '        params = tuple(param for param in self.parameters.values()\n', '                             if param.kind != _KEYWORD_ONLY)\n', '\n', '        kwo_params = {param.name: param for param in self.parameters.values()\n', '                                        if param.kind == _KEYWORD_ONLY}\n', '\n', '        return params, kwo_params, self.return_annotation\n', '\n', '    def __hash__(self):\n', '        params, kwo_params, return_annotation = self._hash_basis()\n', '        kwo_params = frozenset(kwo_params.values())\n', '        return hash((params, kwo_params, return_annotation))\n', '\n', '    def __eq__(self, other):\n', '        if self is other:\n', '            return True\n', '        if not isinstance(other, Signature):\n', '            return NotImplemented\n', '        return self._hash_basis() == other._hash_basis()\n', '\n', '    def _bind(self, args, kwargs, *, partial=False):\n', '        """Private method. Don\'t use directly."""\n', '\n', '        arguments = {}\n', '\n', '        parameters = iter(self.parameters.values())\n', '        parameters_ex = ()\n', '        arg_vals = iter(args)\n', '\n', '        while True:\n', "            # Let's iterate through the positional arguments and corresponding\n", '            # parameters\n', '            try:\n', '                arg_val = next(arg_vals)\n', '            except StopIteration:\n', '                # No more positional arguments\n', '                try:\n', '                    param = next(parameters)\n', '                except StopIteration:\n', "                    # No more parameters. That's it. Just need to check that\n", '                    # we have no `kwargs` after this while loop\n', '                    break\n', '                else:\n', '                    if param.kind == _VAR_POSITIONAL:\n', "                        # That's OK, just empty *args.  Let's start parsing\n", '                        # kwargs\n', '                        break\n', '                    elif param.name in kwargs:\n', '                        if param.kind == _POSITIONAL_ONLY:\n', "                            msg = '{arg!r} parameter is positional only, ' \\\n", "                                  'but was passed as a keyword'\n", '                            msg = msg.format(arg=param.name)\n', '                            raise TypeError(msg) from None\n', '                        parameters_ex = (param,)\n', '                        break\n', '                    elif (param.kind == _VAR_KEYWORD or\n', '                                                param.default is not _empty):\n', "                        # That's fine too - we have a default value for this\n", '                        # parameter.  So, lets start parsing `kwargs`, starting\n', '                        # with the current parameter\n', '                        parameters_ex = (param,)\n', '                        break\n', '                    else:\n', '                        # No default, not VAR_KEYWORD, not VAR_POSITIONAL,\n', '                        # not in `kwargs`\n', '                        if partial:\n', '                            parameters_ex = (param,)\n', '                            break\n', '                        else:\n', "                            msg = 'missing a required argument: {arg!r}'\n", '                            msg = msg.format(arg=param.name)\n', '                            raise TypeError(msg) from None\n', '            else:\n', '                # We have a positional argument to process\n', '                try:\n', '                    param = next(parameters)\n', '                except StopIteration:\n', "                    raise TypeError('too many positional arguments') from None\n", '                else:\n', '                    if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):\n', '                        # Looks like we have no parameter for this positional\n', '                        # argument\n', '                        raise TypeError(\n', "                            'too many positional arguments') from None\n", '\n', '                    if param.kind == _VAR_POSITIONAL:\n', "                        # We have an '*args'-like argument, let's fill it with\n", '                        # all positional arguments we have left and move on to\n', '                        # the next phase\n', '                        values = [arg_val]\n', '                        values.extend(arg_vals)\n', '                        arguments[param.name] = tuple(values)\n', '                        break\n', '\n', '                    if param.name in kwargs and param.kind != _POSITIONAL_ONLY:\n', '                        raise TypeError(\n', "                            'multiple values for argument {arg!r}'.format(\n", '                                arg=param.name)) from None\n', '\n', '                    arguments[param.name] = arg_val\n', '\n', '        # Now, we iterate through the remaining parameters to process\n', '        # keyword arguments\n', '        kwargs_param = None\n', '        for param in itertools.chain(parameters_ex, parameters):\n', '            if param.kind == _VAR_KEYWORD:\n', "                # Memorize that we have a '**kwargs'-like parameter\n", '                kwargs_param = param\n', '                continue\n', '\n', '            if param.kind == _VAR_POSITIONAL:\n', "                # Named arguments don't refer to '*args'-like parameters.\n", '                # We only arrive here if the positional arguments ended\n', '                # before reaching the last parameter before *args.\n', '                continue\n', '\n', '            param_name = param.name\n', '            try:\n', '                arg_val = kwargs.pop(param_name)\n', '            except KeyError:\n', "                # We have no value for this parameter.  It's fine though,\n", "                # if it has a default value, or it is an '*args'-like\n", '                # parameter, left alone by the processing of positional\n', '                # arguments.\n', '                if (not partial and param.kind != _VAR_POSITIONAL and\n', '                                                    param.default is _empty):\n', "                    raise TypeError('missing a required argument: {arg!r}'. \\\n", '                                    format(arg=param_name)) from None\n', '\n', '            else:\n', '                if param.kind == _POSITIONAL_ONLY:\n', '                    # This should never happen in case of a properly built\n', "                    # Signature object (but let's have this check here\n", '                    # to ensure correct behaviour just in case)\n', "                    raise TypeError('{arg!r} parameter is positional only, '\n", "                                    'but was passed as a keyword'. \\\n", '                                    format(arg=param.name))\n', '\n', '                arguments[param_name] = arg_val\n', '\n', '        if kwargs:\n', '            if kwargs_param is not None:\n', "                # Process our '**kwargs'-like parameter\n", '                arguments[kwargs_param.name] = kwargs\n', '            else:\n', '                raise TypeError(\n', "                    'got an unexpected keyword argument {arg!r}'.format(\n", '                        arg=next(iter(kwargs))))\n', '\n', '        return self._bound_arguments_cls(self, arguments)\n', '\n', '    def bind(self, /, *args, **kwargs):\n', '        """Get a BoundArguments object, that maps the passed `args`\n', "        and `kwargs` to the function's signature.  Raises `TypeError`\n", '        if the passed arguments can not be bound.\n', '        """\n', '        return self._bind(args, kwargs)\n', '\n', '    def bind_partial(self, /, *args, **kwargs):\n', '        """Get a BoundArguments object, that partially maps the\n', "        passed `args` and `kwargs` to the function's signature.\n", '        Raises `TypeError` if the passed arguments can not be bound.\n', '        """\n', '        return self._bind(args, kwargs, partial=True)\n', '\n', '    def __reduce__(self):\n', '        return (type(self),\n', '                (tuple(self._parameters.values()),),\n', "                {'_return_annotation': self._return_annotation})\n", '\n', '    def __setstate__(self, state):\n', "        self._return_annotation = state['_return_annotation']\n", '\n', '    def __repr__(self):\n', "        return '<{} {}>'.format(self.__class__.__name__, self)\n", '\n', '    def __str__(self):\n', '        result = []\n', '        render_pos_only_separator = False\n', '        render_kw_only_separator = True\n', '        for param in self.parameters.values():\n', '            formatted = str(param)\n', '\n', '            kind = param.kind\n', '\n', '            if kind == _POSITIONAL_ONLY:\n', '                render_pos_only_separator = True\n', '            elif render_pos_only_separator:\n', "                # It's not a positional-only parameter, and the flag\n", "                # is set to 'True' (there were pos-only params before.)\n", "                result.append('/')\n", '                render_pos_only_separator = False\n', '\n', '            if kind == _VAR_POSITIONAL:\n', "                # OK, we have an '*args'-like parameter, so we won't need\n", "                # a '*' to separate keyword-only arguments\n", '                render_kw_only_separator = False\n', '            elif kind == _KEYWORD_ONLY and render_kw_only_separator:\n', "                # We have a keyword-only parameter to render and we haven't\n", "                # rendered an '*args'-like parameter before, so add a '*'\n", '                # separator to the parameters list ("foo(arg1, *, arg2)" case)\n', "                result.append('*')\n", '                # This condition should be only triggered once, so\n', '                # reset the flag\n', '                render_kw_only_separator = False\n', '\n', '            result.append(formatted)\n', '\n', '        if render_pos_only_separator:\n', '            # There were only positional-only parameters, hence the\n', "            # flag was not reset to 'False'\n", "            result.append('/')\n", '\n', "        rendered = '({})'.format(', '.join(result))\n", '\n', '        if self.return_annotation is not _empty:\n', '            anno = formatannotation(self.return_annotation)\n', "            rendered += ' -> {}'.format(anno)\n", '\n', '        return rendered\n', '\n', '\n', 'def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False):\n', '    """Get a signature object for the passed callable."""\n', '    return Signature.from_callable(obj, follow_wrapped=follow_wrapped,\n', '                                   globals=globals, locals=locals, eval_str=eval_str)\n', '\n', '\n', 'def _main():\n', '    """ Logic for inspecting an object given at command line """\n', '    import argparse\n', '    import importlib\n', '\n', '    parser = argparse.ArgumentParser()\n', '    parser.add_argument(\n', "        'object',\n", '         help="The object to be analysed. "\n', '              "It supports the \'module:qualname\' syntax")\n', '    parser.add_argument(\n', "        '-d', '--details', action='store_true',\n", "        help='Display info about the module rather than its source code')\n", '\n', '    args = parser.parse_args()\n', '\n', '    target = args.object\n', '    mod_name, has_attrs, attrs = target.partition(":")\n', '    try:\n', '        obj = module = importlib.import_module(mod_name)\n', '    except Exception as exc:\n', '        msg = "Failed to import {} ({}: {})".format(mod_name,\n', '                                                    type(exc).__name__,\n', '                                                    exc)\n', '        print(msg, file=sys.stderr)\n', '        sys.exit(2)\n', '\n', '    if has_attrs:\n', '        parts = attrs.split(".")\n', '        obj = module\n', '        for part in parts:\n', '            obj = getattr(obj, part)\n', '\n', '    if module.__name__ in sys.builtin_module_names:\n', '        print("Can\'t get info for builtin modules.", file=sys.stderr)\n', '        sys.exit(1)\n', '\n', '    if args.details:\n', "        print('Target: {}'.format(target))\n", "        print('Origin: {}'.format(getsourcefile(module)))\n", "        print('Cached: {}'.format(module.__cached__))\n", '        if obj is module:\n', "            print('Loader: {}'.format(repr(module.__loader__)))\n", "            if hasattr(module, '__path__'):\n", "                print('Submodule search path: {}'.format(module.__path__))\n", '        else:\n', '            try:\n', '                __, lineno = findsource(obj)\n', '            except Exception:\n', '                pass\n', '            else:\n', "                print('Line: {}'.format(lineno))\n", '\n', "        print('\\n')\n", '    else:\n', '        print(getsource(obj))\n', '\n', '\n', 'if __name__ == "__main__":\n', '    _main()\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/inspect.py'), '/nix/store/lsvw498hh26fv6kdp8x1khlc60j6fc39-python3.10-amethyst_extensions-0.0.1/lib/python3.10/site-packages/amethyst_ext/pydoc.py': (6978, 1.0, ['from amethyst.response import Response, Status\n', '\n', 'import importlib\n', 'import inspect\n', 'import pkgutil\n', 'import re\n', 'import sys\n', 'import textwrap\n', '\n', 'SITE_PACKAGES_RE = re.compile(r"lib/python[^/]+/site-packages")\n', 'PYTHON3_RE = re.compile(r"python3[^-]*")\n', '\n', '\n', 'class PydocResource:\n', '    @staticmethod\n', '    def classify(thing):\n', '        if inspect.ismodule(thing):\n', '            return "module"\n', '        elif inspect.isclass(thing):\n', '            return "class"\n', '        elif (\n', '            inspect.isfunction(thing)\n', '            or inspect.ismethod(thing)\n', '            or inspect.ismethoddescriptor(thing)\n', '            or inspect.isroutine(thing)\n', '        ):\n', '            return "function"\n', '        else:\n', '            return "other"\n', '\n', '    def doc_class(self, cls, name=None):\n', '        lines = []\n', '\n', '        if name is None:\n', '            name = cls.__name__\n', '        else:\n', '            name = f"{name}.{cls.__name__}"\n', '\n', '        lines.append(f"### {name}")\n', '        if clsdoc := getattr(cls, "__doc__"):\n', '            lines.append(f"```\\n{clsdoc}\\n```\\n")\n', '\n', '        members = {}\n', '        members = {"class": [], "function": [], "other": []}\n', '\n', '        for name, member in inspect.getmembers(cls):\n', '            if name.startswith("_"):\n', '                continue\n', '\n', '            if (classification := self.classify(member)) in {\n', '                "class",\n', '                "function",\n', '                "other",\n', '            }:\n', '                members[classification].append((name, member))\n', '\n', '        members["class"].sort()\n', '        for _, scls in members["class"]:\n', '            lines.append(self.doc_class(scls, name))\n', '\n', '        members["function"].sort()\n', '        for name, func in members["function"]:\n', '            lines.append(self.doc_func(func))\n', '\n', '        members["other"].sort()\n', '        for name, other in members["other"]:\n', '            lines.append(self.doc_other(name, other))\n', '\n', '        return "\\n".join(lines)\n', '\n', '    def doc_func(self, func):\n', '        lines = []\n', '\n', '        lines.append("```")\n', '        try:\n', '            lines.append(f"{func.__name__}{inspect.signature(func)}")\n', '        except ValueError:\n', '            lines.append(f"{func.__name__}(...)")\n', '\n', '        if funcdoc := getattr(func, "__doc__"):\n', '            lines.append(f"\\n{textwrap.indent(funcdoc, \'  \')}\\n```\\n")\n', '        else:\n', '            lines.append("```\\n")\n', '\n', '        return "\\n".join(lines)\n', '\n', '    def doc_other(self, name, other):\n', '        doc = getattr(other, "__doc__", "")\n', '        if doc and doc != type(other).__doc__:\n', '            doc = textwrap.indent(doc, "  ")\n', '            doc += "\\n```\\n"\n', '        else:\n', '            doc = "```"\n', '\n', '        return f"```\\n{name} = {other!r}\\n{doc}"\n', '\n', '    def doc_mod(self, modname):\n', '        lines = []\n', '\n', '        try:\n', '            module = importlib.import_module(modname)\n', '        except ImportError:\n', '            return None\n', '\n', '        ispkg = getattr(module, "__package__", "") == modname\n', '\n', '        lines.append("=> _ Back to module index")\n', '        lines.append("=> _/search Go to module by name")\n', '        if "." in modname:\n', '            components = modname.split(".")\n', '            for i in range(len(components) - 1, 0, -1):\n', '                lines.append("=> " + ".".join(components[:i]))\n', '\n', '        if ispkg:\n', '            lines.append(f"# {modname} (package)")\n', '        else:\n', '            lines.append(f"# {modname}")\n', '\n', '        if moddoc := getattr(module, "__doc__"):\n', '            lines.append(f"```\\n{moddoc}\\n```")\n', '        else:\n', '            lines.append("This module has no docstring.")\n', '\n', '        members = {"module": [], "class": [], "function": [], "other": []}\n', '        for name, member in inspect.getmembers(module):\n', '            if name.startswith("_"):\n', '                continue\n', '\n', '            members[self.classify(member)].append((name, member))\n', '\n', '        if members["class"]:\n', '            members["class"].sort()\n', '            lines.append("## Classes")\n', '            for name, cls in members["class"]:\n', '                lines.append(self.doc_class(cls))\n', '\n', '        if members["function"]:\n', '            members["function"].sort()\n', '            lines.append("## Functions")\n', '            for name, func in members["function"]:\n', '                lines.append(f"### {name}")\n', '                lines.append(self.doc_func(func))\n', '\n', '        if members["other"]:\n', '            lines.append("## Other members")\n', '            members["other"].sort()\n', '            for name, other in members["other"]:\n', '                lines.append(self.doc_other(name, other))\n', '\n', '        if members["module"]:\n', '            members["module"].sort()\n', '            lines.append("## Modules")\n', '            for name, mod in members["module"]:\n', '                lines.append(f"=> {mod.__name__} {name}")\n', '\n', '        return "\\n".join(lines)\n', '\n', '    def index(self):\n', '        lines = []\n', '\n', '        lines.append("=> _/search Go to module by name")\n', '\n', '        lines.append("# Built-in modules")\n', '        names = [name for name in sys.builtin_module_names if name != "__main__"]\n', '        for name in sorted(names):\n', '            lines.append(f"=> {name}")\n', '\n', '        lines.append("# Python modules")\n', '        for dirname in sorted(sys.path):\n', '            display = dirname\n', '            if display.startswith("/nix/store/"):\n', '                display = f"(nix)/{display[44:]}"\n', '\n', '            display = SITE_PACKAGES_RE.sub("l/p/s-p", display)\n', '            display = PYTHON3_RE.sub("p3", display)\n', '\n', '            modpkgs = []\n', '            for importer, name, ispkg in pkgutil.iter_modules([dirname]):\n', '                if any((0xD800 <= ord(ch) <= 0xDFFF) for ch in name):\n', '                    # Ignore modules that contain surrogate characters\n', '                    # (pydoc does this)\n', '                    continue\n', '\n', '                if name == "setup":\n', '                    # never import "setup.py"\n', '                    continue\n', '\n', '                modpkgs.append((name, ispkg))\n', '\n', '            if modpkgs:\n', '                lines.append(f"## {display}")\n', '                for name, ispkg in sorted(modpkgs):\n', '                    if ispkg:\n', '                        lines.append(f"=> {name} {name} (package)")\n', '                    else:\n', '                        lines.append(f"=> {name}")\n', '\n', '        return "\\n".join(lines)\n', '\n', '    async def __call__(self, ctx):\n', '        path = ctx.path\n', '        if not path:\n', '            return Response(Status.REDIRECT_PERMANENT, ctx.orig_path + "/")\n', '\n', '        path = path.strip("/")\n', '        if not path or path == "_":\n', '            text = self.index()\n', '\n', '        elif path == "_/search":\n', '            if ctx.query:\n', '                try:\n', '                    importlib.import_module(ctx.query)\n', '                    return Response(Status.REDIRECT_TEMPORARY, "../" + ctx.query)\n', '                except ImportError:\n', '                    return Response(\n', '                        Status.INPUT,\n', '                        f"Sorry, I don\'t know about {ctx.query}. Module name?",\n', '                    )\n', '\n', '            return Response(Status.INPUT, "Module name?")\n', '        else:\n', '            text = self.doc_mod(path)\n', '\n', '        if text is not None:\n', '            return Response(Status.SUCCESS, "text/gemini", text.encode())\n', '\n', '        return Response(Status.NOT_FOUND, "text/gemini")\n'], '/nix/store/lsvw498hh26fv6kdp8x1khlc60j6fc39-python3.10-amethyst_extensions-0.0.1/lib/python3.10/site-packages/amethyst_ext/pydoc.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/pydoc.py': (109589, 1.0, ['#!/usr/bin/env python3\n', '"""Generate Python documentation in HTML or text for interactive use.\n', '\n', 'At the Python interactive prompt, calling help(thing) on a Python object\n', 'documents the object, and calling help() starts up an interactive\n', 'help session.\n', '\n', 'Or, at the shell command line outside of Python:\n', '\n', 'Run "pydoc <name>" to show documentation on something.  <name> may be\n', 'the name of a function, module, package, or a dotted reference to a\n', 'class or function within a module or module in a package.  If the\n', 'argument contains a path segment delimiter (e.g. slash on Unix,\n', 'backslash on Windows) it is treated as the path to a Python source file.\n', '\n', 'Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines\n', 'of all available modules.\n', '\n', 'Run "pydoc -n <hostname>" to start an HTTP server with the given\n', 'hostname (default: localhost) on the local machine.\n', '\n', 'Run "pydoc -p <port>" to start an HTTP server on the given port on the\n', 'local machine.  Port number 0 can be used to get an arbitrary unused port.\n', '\n', 'Run "pydoc -b" to start an HTTP server on an arbitrary unused port and\n', 'open a web browser to interactively browse documentation.  Combine with\n', 'the -n and -p options to control the hostname and port used.\n', '\n', 'Run "pydoc -w <name>" to write out the HTML documentation for a module\n', 'to a file named "<name>.html".\n', '\n', 'Module docs for core modules are assumed to be in\n', '\n', '    https://docs.python.org/X.Y/library/\n', '\n', 'This can be overridden by setting the PYTHONDOCS environment variable\n', 'to a different URL or to a local directory containing the Library\n', 'Reference Manual pages.\n', '"""\n', "__all__ = ['help']\n", '__author__ = "Ka-Ping Yee <ping@lfw.org>"\n', '__date__ = "26 February 2001"\n', '\n', '__credits__ = """Guido van Rossum, for an excellent programming language.\n', 'Tommy Burnette, the original creator of manpy.\n', 'Paul Prescod, for all his work on onlinehelp.\n', 'Richard Chamberlain, for the first implementation of textdoc.\n', '"""\n', '\n', "# Known bugs that can't be fixed here:\n", '#   - synopsis() cannot be prevented from clobbering existing\n', '#     loaded modules.\n', '#   - If the __file__ attribute on a module is a relative path and\n', '#     the current directory is changed with os.chdir(), an incorrect\n', '#     path will be displayed.\n', '\n', 'import builtins\n', 'import importlib._bootstrap\n', 'import importlib._bootstrap_external\n', 'import importlib.machinery\n', 'import importlib.util\n', 'import inspect\n', 'import io\n', 'import os\n', 'import pkgutil\n', 'import platform\n', 'import re\n', 'import sys\n', 'import sysconfig\n', 'import time\n', 'import tokenize\n', 'import types\n', 'import urllib.parse\n', 'import warnings\n', 'from collections import deque\n', 'from reprlib import Repr\n', 'from traceback import format_exception_only\n', '\n', '\n', '# --------------------------------------------------------- common routines\n', '\n', 'def pathdirs():\n', '    """Convert sys.path into a list of absolute, existing, unique paths."""\n', '    dirs = []\n', '    normdirs = []\n', '    for dir in sys.path:\n', "        dir = os.path.abspath(dir or '.')\n", '        normdir = os.path.normcase(dir)\n', '        if normdir not in normdirs and os.path.isdir(dir):\n', '            dirs.append(dir)\n', '            normdirs.append(normdir)\n', '    return dirs\n', '\n', 'def _isclass(object):\n', '    return inspect.isclass(object) and not isinstance(object, types.GenericAlias)\n', '\n', 'def _findclass(func):\n', '    cls = sys.modules.get(func.__module__)\n', '    if cls is None:\n', '        return None\n', "    for name in func.__qualname__.split('.')[:-1]:\n", '        cls = getattr(cls, name)\n', '    if not _isclass(cls):\n', '        return None\n', '    return cls\n', '\n', 'def _finddoc(obj):\n', '    if inspect.ismethod(obj):\n', '        name = obj.__func__.__name__\n', '        self = obj.__self__\n', '        if (_isclass(self) and\n', "            getattr(getattr(self, name, None), '__func__') is obj.__func__):\n", '            # classmethod\n', '            cls = self\n', '        else:\n', '            cls = self.__class__\n', '    elif inspect.isfunction(obj):\n', '        name = obj.__name__\n', '        cls = _findclass(obj)\n', '        if cls is None or getattr(cls, name) is not obj:\n', '            return None\n', '    elif inspect.isbuiltin(obj):\n', '        name = obj.__name__\n', '        self = obj.__self__\n', '        if (_isclass(self) and\n', "            self.__qualname__ + '.' + name == obj.__qualname__):\n", '            # classmethod\n', '            cls = self\n', '        else:\n', '            cls = self.__class__\n', '    # Should be tested before isdatadescriptor().\n', '    elif isinstance(obj, property):\n', '        func = obj.fget\n', '        name = func.__name__\n', '        cls = _findclass(func)\n', '        if cls is None or getattr(cls, name) is not obj:\n', '            return None\n', '    elif inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj):\n', '        name = obj.__name__\n', '        cls = obj.__objclass__\n', '        if getattr(cls, name) is not obj:\n', '            return None\n', '        if inspect.ismemberdescriptor(obj):\n', "            slots = getattr(cls, '__slots__', None)\n", '            if isinstance(slots, dict) and name in slots:\n', '                return slots[name]\n', '    else:\n', '        return None\n', '    for base in cls.__mro__:\n', '        try:\n', '            doc = _getowndoc(getattr(base, name))\n', '        except AttributeError:\n', '            continue\n', '        if doc is not None:\n', '            return doc\n', '    return None\n', '\n', 'def _getowndoc(obj):\n', '    """Get the documentation string for an object if it is not\n', '    inherited from its class."""\n', '    try:\n', "        doc = object.__getattribute__(obj, '__doc__')\n", '        if doc is None:\n', '            return None\n', '        if obj is not type:\n', '            typedoc = type(obj).__doc__\n', '            if isinstance(typedoc, str) and typedoc == doc:\n', '                return None\n', '        return doc\n', '    except AttributeError:\n', '        return None\n', '\n', 'def _getdoc(object):\n', '    """Get the documentation string for an object.\n', '\n', '    All tabs are expanded to spaces.  To clean up docstrings that are\n', '    indented to line up with blocks of code, any whitespace than can be\n', '    uniformly removed from the second line onwards is removed."""\n', '    doc = _getowndoc(object)\n', '    if doc is None:\n', '        try:\n', '            doc = _finddoc(object)\n', '        except (AttributeError, TypeError):\n', '            return None\n', '    if not isinstance(doc, str):\n', '        return None\n', '    return inspect.cleandoc(doc)\n', '\n', 'def getdoc(object):\n', '    """Get the doc string or comments for an object."""\n', '    result = _getdoc(object) or inspect.getcomments(object)\n', "    return result and re.sub('^ *\\n', '', result.rstrip()) or ''\n", '\n', 'def splitdoc(doc):\n', '    """Split a doc string into a synopsis line (if any) and the rest."""\n', "    lines = doc.strip().split('\\n')\n", '    if len(lines) == 1:\n', "        return lines[0], ''\n", '    elif len(lines) >= 2 and not lines[1].rstrip():\n', "        return lines[0], '\\n'.join(lines[2:])\n", "    return '', '\\n'.join(lines)\n", '\n', 'def classname(object, modname):\n', '    """Get a class name and qualify it with a module name if necessary."""\n', '    name = object.__name__\n', '    if object.__module__ != modname:\n', "        name = object.__module__ + '.' + name\n", '    return name\n', '\n', 'def isdata(object):\n', '    """Check if an object is of a type that probably means it\'s data."""\n', '    return not (inspect.ismodule(object) or _isclass(object) or\n', '                inspect.isroutine(object) or inspect.isframe(object) or\n', '                inspect.istraceback(object) or inspect.iscode(object))\n', '\n', 'def replace(text, *pairs):\n', '    """Do a series of global replacements on a string."""\n', '    while pairs:\n', '        text = pairs[1].join(text.split(pairs[0]))\n', '        pairs = pairs[2:]\n', '    return text\n', '\n', 'def cram(text, maxlen):\n', '    """Omit part of a string if needed to make it fit in a maximum length."""\n', '    if len(text) > maxlen:\n', '        pre = max(0, (maxlen-3)//2)\n', '        post = max(0, maxlen-3-pre)\n', "        return text[:pre] + '...' + text[len(text)-post:]\n", '    return text\n', '\n', "_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)


, re.IGNORECASE)\n", 'def stripid(text):\n', '    """Remove the hexadecimal id from a Python object representation."""\n', '    # The behaviour of %p is implementation-dependent in terms of case.\n', "    return _re_stripid.sub(r'\\1', text)\n", '\n', 'def _is_bound_method(fn):\n', '    """\n', '    Returns True if fn is a bound method, regardless of whether\n', '    fn was implemented in Python or in C.\n', '    """\n', '    if inspect.ismethod(fn):\n', '        return True\n', '    if inspect.isbuiltin(fn):\n', "        self = getattr(fn, '__self__', None)\n", '        return not (inspect.ismodule(self) or (self is None))\n', '    return False\n', '\n', '\n', 'def allmethods(cl):\n', '    methods = {}\n', '    for key, value in inspect.getmembers(cl, inspect.isroutine):\n', '        methods[key] = 1\n', '    for base in cl.__bases__:\n', '        methods.update(allmethods(base)) # all your base are belong to us\n', '    for key in methods.keys():\n', '        methods[key] = getattr(cl, key)\n', '    return methods\n', '\n', 'def _split_list(s, predicate):\n', '    """Split sequence s via predicate, and return pair ([true], [false]).\n', '\n', '    The return value is a 2-tuple of lists,\n', '        ([x for x in s if predicate(x)],\n', '         [x for x in s if not predicate(x)])\n', '    """\n', '\n', '    yes = []\n', '    no = []\n', '    for x in s:\n', '        if predicate(x):\n', '            yes.append(x)\n', '        else:\n', '            no.append(x)\n', '    return yes, no\n', '\n', 'def visiblename(name, all=None, obj=None):\n', '    """Decide whether to show documentation on a variable."""\n', '    # Certain special names are redundant or internal.\n', '    # XXX Remove __initializing__?\n', "    if name in {'__author__', '__builtins__', '__cached__', '__credits__',\n", "                '__date__', '__doc__', '__file__', '__spec__',\n", "                '__loader__', '__module__', '__name__', '__package__',\n", "                '__path__', '__qualname__', '__slots__', '__version__'}:\n", '        return 0\n', '    # Private names are hidden, but special names are displayed.\n', "    if name.startswith('__') and name.endswith('__'): return 1\n", '    # Namedtuples have public fields and methods with a single leading underscore\n', "    if name.startswith('_') and hasattr(obj, '_fields'):\n", '        return True\n', '    if all is not None:\n', '        # only document that which the programmer exported in __all__\n', '        return name in all\n', '    else:\n', "        return not name.startswith('_')\n", '\n', 'def classify_class_attrs(object):\n', '    """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""\n', '    results = []\n', '    for (name, kind, cls, value) in inspect.classify_class_attrs(object):\n', '        if inspect.isdatadescriptor(value):\n', "            kind = 'data descriptor'\n", '            if isinstance(value, property) and value.fset is None:\n', "                kind = 'readonly property'\n", '        results.append((name, kind, cls, value))\n', '    return results\n', '\n', 'def sort_attributes(attrs, object):\n', "    'Sort the attrs list in-place by _fields and then alphabetically by name'\n", '    # This allows data descriptors to be ordered according\n', '    # to a _fields attribute if present.\n', "    fields = getattr(object, '_fields', [])\n", '    try:\n', '        field_order = {name : i-len(fields) for (i, name) in enumerate(fields)}\n', '    except TypeError:\n', '        field_order = {}\n', '    keyfunc = lambda attr: (field_order.get(attr[0], 0), attr[0])\n', '    attrs.sort(key=keyfunc)\n', '\n', '# ----------------------------------------------------- module manipulation\n', '\n', 'def ispackage(path):\n', '    """Guess whether a path refers to a package directory."""\n', '    if os.path.isdir(path):\n', "        for ext in ('.py', '.pyc'):\n", "            if os.path.isfile(os.path.join(path, '__init__' + ext)):\n", '                return True\n', '    return False\n', '\n', 'def source_synopsis(file):\n', '    line = file.readline()\n', "    while line[:1] == '#' or not line.strip():\n", '        line = file.readline()\n', '        if not line: break\n', '    line = line.strip()\n', '    if line[:4] == \'r"""\': line = line[1:]\n', '    if line[:3] == \'"""\':\n', '        line = line[3:]\n', "        if line[-1:] == '\\\\': line = line[:-1]\n", '        while not line.strip():\n', '            line = file.readline()\n', '            if not line: break\n', '        result = line.split(\'"""\')[0].strip()\n', '    else: result = None\n', '    return result\n', '\n', 'def synopsis(filename, cache={}):\n', '    """Get the one-line summary out of a module file."""\n', '    mtime = os.stat(filename).st_mtime\n', '    lastupdate, result = cache.get(filename, (None, None))\n', '    if lastupdate is None or lastupdate < mtime:\n', '        # Look for binary suffixes first, falling back to source.\n', '        if filename.endswith(tuple(importlib.machinery.BYTECODE_SUFFIXES)):\n', '            loader_cls = importlib.machinery.SourcelessFileLoader\n', '        elif filename.endswith(tuple(importlib.machinery.EXTENSION_SUFFIXES)):\n', '            loader_cls = importlib.machinery.ExtensionFileLoader\n', '        else:\n', '            loader_cls = None\n', '        # Now handle the choice.\n', '        if loader_cls is None:\n', '            # Must be a source file.\n', '            try:\n', '                file = tokenize.open(filename)\n', '            except OSError:\n', "                # module can't be opened, so skip it\n", '                return None\n', '            # text modules can be directly examined\n', '            with file:\n', '                result = source_synopsis(file)\n', '        else:\n', '            # Must be a binary module, which has to be imported.\n', "            loader = loader_cls('__temp__', filename)\n", "            # XXX We probably don't need to pass in the loader here.\n", "            spec = importlib.util.spec_from_file_location('__temp__', filename,\n", '                                                          loader=loader)\n', '            try:\n', '                module = importlib._bootstrap._load(spec)\n', '            except:\n', '                return None\n', "            del sys.modules['__temp__']\n", '            result = module.__doc__.splitlines()[0] if module.__doc__ else None\n', '        # Cache the result.\n', '        cache[filename] = (mtime, result)\n', '    return result\n', '\n', 'class ErrorDuringImport(Exception):\n', '    """Errors that occurred while trying to import something to document it."""\n', '    def __init__(self, filename, exc_info):\n', '        self.filename = filename\n', '        self.exc, self.value, self.tb = exc_info\n', '\n', '    def __str__(self):\n', '        exc = self.exc.__name__\n', "        return 'problem in %s - %s: %s' % (self.filename, exc, self.value)\n", '\n', 'def importfile(path):\n', '    """Import a Python source file or compiled file given its path."""\n', '    magic = importlib.util.MAGIC_NUMBER\n', "    with open(path, 'rb') as file:\n", '        is_bytecode = magic == file.read(len(magic))\n', '    filename = os.path.basename(path)\n', '    name, ext = os.path.splitext(filename)\n', '    if is_bytecode:\n', '        loader = importlib._bootstrap_external.SourcelessFileLoader(name, path)\n', '    else:\n', '        loader = importlib._bootstrap_external.SourceFileLoader(name, path)\n', "    # XXX We probably don't need to pass in the loader here.\n", '    spec = importlib.util.spec_from_file_location(name, path, loader=loader)\n', '    try:\n', '        return importlib._bootstrap._load(spec)\n', '    except:\n', '        raise ErrorDuringImport(path, sys.exc_info())\n', '\n', 'def safeimport(path, forceload=0, cache={}):\n', '    """Import a module; handle errors; return None if the module isn\'t found.\n', '\n', "    If the module *is* found but an exception occurs, it's wrapped in an\n", '    ErrorDuringImport exception and reraised.  Unlike __import__, if a\n', '    package path is specified, the module at the end of the path is returned,\n', "    not the package at the beginning.  If the optional 'forceload' argument\n", '    is 1, we reload the module from disk (unless it\'s a dynamic extension)."""\n', '    try:\n', '        # If forceload is 1 and the module has been previously loaded from\n', "        # disk, we always have to reload the module.  Checking the file's\n", "        # mtime isn't good enough (e.g. the module could contain a class\n", '        # that inherits from another module that has changed).\n', '        if forceload and path in sys.modules:\n', '            if path not in sys.builtin_module_names:\n', '                # Remove the module from sys.modules and re-import to try\n', '                # and avoid problems with partially loaded modules.\n', "                # Also remove any submodules because they won't appear\n", "                # in the newly loaded module's namespace if they're already\n", '                # in sys.modules.\n', "                subs = [m for m in sys.modules if m.startswith(path + '.')]\n", '                for key in [path] + subs:\n', '                    # Prevent garbage collection.\n', '                    cache[key] = sys.modules[key]\n', '                    del sys.modules[key]\n', '        module = __import__(path)\n', '    except:\n', '        # Did the error occur before or after the module was found?\n', '        (exc, value, tb) = info = sys.exc_info()\n', '        if path in sys.modules:\n', '            # An error occurred while executing the imported module.\n', '            raise ErrorDuringImport(sys.modules[path].__file__, info)\n', '        elif exc is SyntaxError:\n', '            # A SyntaxError occurred before we could execute the module.\n', '            raise ErrorDuringImport(value.filename, info)\n', '        elif issubclass(exc, ImportError) and value.name == path:\n', '            # No such module in the path.\n', '            return None\n', '        else:\n', '            # Some other error occurred during the importing process.\n', '            raise ErrorDuringImport(path, sys.exc_info())\n', "    for part in path.split('.')[1:]:\n", '        try: module = getattr(module, part)\n', '        except AttributeError: return None\n', '    return module\n', '\n', '# ---------------------------------------------------- formatter base class\n', '\n', 'class Doc:\n', '\n', '    PYTHONDOCS = os.environ.get("PYTHONDOCS",\n', '                                "https://docs.python.org/%d.%d/library"\n', '                                % sys.version_info[:2])\n', '\n', '    def document(self, object, name=None, *args):\n', '        """Generate documentation for an object."""\n', '        args = (object, name) + args\n', "        # 'try' clause is to attempt to handle the possibility that inspect\n", '        # identifies something in a way that pydoc itself has issues handling;\n', "        # think 'super' and how it is a descriptor (which raises the exception\n", '        # by lacking a __name__ attribute) and an instance.\n', '        try:\n', '            if inspect.ismodule(object): return self.docmodule(*args)\n', '            if _isclass(object): return self.docclass(*args)\n', '            if inspect.isroutine(object): return self.docroutine(*args)\n', '        except AttributeError:\n', '            pass\n', '        if inspect.isdatadescriptor(object): return self.docdata(*args)\n', '        return self.docother(*args)\n', '\n', '    def fail(self, object, name=None, *args):\n', '        """Raise an exception for unimplemented types."""\n', '        message = "don\'t know how to document object%s of type %s" % (\n', "            name and ' ' + repr(name), type(object).__name__)\n", '        raise TypeError(message)\n', '\n', '    docmodule = docclass = docroutine = docother = docproperty = docdata = fail\n', '\n', "    def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')):\n", '        """Return the location of module docs or None"""\n', '\n', '        try:\n', '            file = inspect.getabsfile(object)\n', '        except TypeError:\n', "            file = '(built-in)'\n", '\n', '        docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)\n', '\n', '        basedir = os.path.normcase(basedir)\n', '        if (isinstance(object, type(os)) and\n', "            (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',\n", "                                 'marshal', 'posix', 'signal', 'sys',\n", "                                 '_thread', 'zipimport') or\n", '             (file.startswith(basedir) and\n', "              not file.startswith(os.path.join(basedir, 'site-packages')))) and\n", "            object.__name__ not in ('xml.etree', 'test.pydoc_mod')):\n", '            if docloc.startswith(("http://", "https://")):\n', '                docloc = "{}/{}.html".format(docloc.rstrip("/"), object.__name__.lower())\n', '            else:\n', '                docloc = os.path.join(docloc, object.__name__.lower() + ".html")\n', '        else:\n', '            docloc = None\n', '        return docloc\n', '\n', '# -------------------------------------------- HTML documentation generator\n', '\n', 'class HTMLRepr(Repr):\n', '    """Class for safely making an HTML representation of a Python object."""\n', '    def __init__(self):\n', '        Repr.__init__(self)\n', '        self.maxlist = self.maxtuple = 20\n', '        self.maxdict = 10\n', '        self.maxstring = self.maxother = 100\n', '\n', '    def escape(self, text):\n', "        return replace(text, '&', '&amp;', '<', '&lt;', '>', '&gt;')\n", '\n', '    def repr(self, object):\n', '        return Repr.repr(self, object)\n', '\n', '    def repr1(self, x, level):\n', "        if hasattr(type(x), '__name__'):\n", "            methodname = 'repr_' + '_'.join(type(x).__name__.split())\n", '            if hasattr(self, methodname):\n', '                return getattr(self, methodname)(x, level)\n', '        return self.escape(cram(stripid(repr(x)), self.maxother))\n', '\n', '    def repr_string(self, x, level):\n', '        test = cram(x, self.maxstring)\n', '        testrepr = repr(test)\n', "        if '\\\\' in test and '\\\\' not in replace(testrepr, r'\\\\', ''):\n", '            # Backslashes are only literal in the string and are never\n', '            # needed to make any special characters, so show a raw string.\n', "            return 'r' + testrepr[0] + self.escape(test) + testrepr[0]\n", '        return re.sub(r\'((\\\\[\\\\abfnrtv\\\'"]|\\\\[0-9]..|\\\\x..|\\\\u....)+)\',\n', '                      r\'<font color="#c040c0">\\1</font>\',\n', '                      self.escape(testrepr))\n', '\n', '    repr_str = repr_string\n', '\n', '    def repr_instance(self, x, level):\n', '        try:\n', '            return self.escape(cram(stripid(repr(x)), self.maxstring))\n', '        except:\n', "            return self.escape('<%s instance>' % x.__class__.__name__)\n", '\n', '    repr_unicode = repr_string\n', '\n', 'class HTMLDoc(Doc):\n', '    """Formatter class for HTML documentation."""\n', '\n', '    # ------------------------------------------- HTML formatting utilities\n', '\n', '    _repr_instance = HTMLRepr()\n', '    repr = _repr_instance.repr\n', '    escape = _repr_instance.escape\n', '\n', '    def page(self, title, contents):\n', '        """Format an HTML page."""\n', "        return '''\\\n", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\n', '<html><head><title>Python: %s</title>\n', '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n', '</head><body bgcolor="#f0f0f8">\n', '%s\n', "</body></html>''' % (title, contents)\n", '\n', "    def heading(self, title, fgcol, bgcol, extras=''):\n", '        """Format a page heading."""\n', "        return '''\n", '<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">\n', '<tr bgcolor="%s">\n', '<td valign=bottom>&nbsp;<br>\n', '<font color="%s" face="helvetica, arial">&nbsp;<br>%s</font></td\n', '><td align=right valign=bottom\n', '><font color="%s" face="helvetica, arial">%s</font></td></tr></table>\n', "    ''' % (bgcol, fgcol, title, fgcol, extras or '&nbsp;')\n", '\n', '    def section(self, title, fgcol, bgcol, contents, width=6,\n', "                prelude='', marginalia=None, gap='&nbsp;'):\n", '        """Format a section with a heading."""\n', '        if marginalia is None:\n', "            marginalia = '<tt>' + '&nbsp;' * width + '</tt>'\n", "        result = '''<p>\n", '<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">\n', '<tr bgcolor="%s">\n', '<td colspan=3 valign=bottom>&nbsp;<br>\n', '<font color="%s" face="helvetica, arial">%s</font></td></tr>\n', "    ''' % (bgcol, fgcol, title)\n", '        if prelude:\n', "            result = result + '''\n", '<tr bgcolor="%s"><td rowspan=2>%s</td>\n', '<td colspan=2>%s</td></tr>\n', "<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)\n", '        else:\n', "            result = result + '''\n", '<tr><td bgcolor="%s">%s</td><td>%s</td>\'\'\' % (bgcol, marginalia, gap)\n', '\n', '        return result + \'\\n<td width="100%%">%s</td></tr></table>\' % contents\n', '\n', '    def bigsection(self, title, *args):\n', '        """Format a section with a big heading."""\n', "        title = '<big><strong>%s</strong></big>' % title\n", '        return self.section(title, *args)\n', '\n', '    def preformat(self, text):\n', '        """Format literal preformatted text."""\n', '        text = self.escape(text.expandtabs())\n', "        return replace(text, '\\n\\n', '\\n \\n', '\\n\\n', '\\n \\n',\n", "                             ' ', '&nbsp;', '\\n', '<br>\\n')\n", '\n', '    def multicolumn(self, list, format, cols=4):\n', '        """Format a list of items into a multi-column list."""\n', "        result = ''\n", '        rows = (len(list)+cols-1)//cols\n', '        for col in range(cols):\n', '            result = result + \'<td width="%d%%" valign=top>\' % (100//cols)\n', '            for i in range(rows*col, rows*col+rows):\n', '                if i < len(list):\n', "                    result = result + format(list[i]) + '<br>\\n'\n", "            result = result + '</td>'\n", '        return \'<table width="100%%" summary="list"><tr>%s</tr></table>\' % result\n', '\n', '    def grey(self, text): return \'<font color="#909090">%s</font>\' % text\n', '\n', '    def namelink(self, name, *dicts):\n', '        """Make a link for an identifier, given name-to-URL mappings."""\n', '        for dict in dicts:\n', '            if name in dict:\n', '                return \'<a href="%s">%s</a>\' % (dict[name], name)\n', '        return name\n', '\n', '    def classlink(self, object, modname):\n', '        """Make a link for a class."""\n', '        name, module = object.__name__, sys.modules.get(object.__module__)\n', '        if hasattr(module, name) and getattr(module, name) is object:\n', '            return \'<a href="%s.html#%s">%s</a>\' % (\n', '                module.__name__, name, classname(object, modname))\n', '        return classname(object, modname)\n', '\n', '    def modulelink(self, object):\n', '        """Make a link for a module."""\n', '        return \'<a href="%s.html">%s</a>\' % (object.__name__, object.__name__)\n', '\n', '    def modpkglink(self, modpkginfo):\n', '        """Make a link for a module or package to display in an index."""\n', '        name, path, ispackage, shadowed = modpkginfo\n', '        if shadowed:\n', '            return self.grey(name)\n', '        if path:\n', "            url = '%s.%s.html' % (path, name)\n", '        else:\n', "            url = '%s.html' % name\n", '        if ispackage:\n', "            text = '<strong>%s</strong>&nbsp;(package)' % name\n", '        else:\n', '            text = name\n', '        return \'<a href="%s">%s</a>\' % (url, text)\n', '\n', '    def filelink(self, url, path):\n', '        """Make a link to source file."""\n', '        return \'<a href="file:%s">%s</a>\' % (url, path)\n', '\n', '    def markup(self, text, escape=None, funcs={}, classes={}, methods={}):\n', '        """Mark up some plain text, given a context of symbols to look for.\n', '        Each context dictionary maps object names to anchor names."""\n', '        escape = escape or self.escape\n', '        results = []\n', '        here = 0\n', "        pattern = re.compile(r'\\b((http|https|ftp)://\\S+[\\w/]|'\n", "                                r'RFC[- ]?(\\d+)|'\n", "                                r'PEP[- ]?(\\d+)|'\n", "                                r'(self\\.)?(\\w+))')\n", '        while True:\n', '            match = pattern.search(text, here)\n', '            if not match: break\n', '            start, end = match.span()\n', '            results.append(escape(text[here:start]))\n', '\n', '            all, scheme, rfc, pep, selfdot, name = match.groups()\n', '            if scheme:\n', '                url = escape(all).replace(\'"\', \'&quot;\')\n', '                results.append(\'<a href="%s">%s</a>\' % (url, url))\n', '            elif rfc:\n', "                url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)\n", '                results.append(\'<a href="%s">%s</a>\' % (url, escape(all)))\n', '            elif pep:\n', "                url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep)\n", '                results.append(\'<a href="%s">%s</a>\' % (url, escape(all)))\n', '            elif selfdot:\n', "                # Create a link for methods like 'self.method(...)'\n", "                # and use <strong> for attributes like 'self.attr'\n", "                if text[end:end+1] == '(':\n", "                    results.append('self.' + self.namelink(name, methods))\n", '                else:\n', "                    results.append('self.<strong>%s</strong>' % name)\n", "            elif text[end:end+1] == '(':\n", '                results.append(self.namelink(name, methods, funcs, classes))\n', '            else:\n', '                results.append(self.namelink(name, classes))\n', '            here = end\n', '        results.append(escape(text[here:]))\n', "        return ''.join(results)\n", '\n', '    # ---------------------------------------------- type-specific routines\n', '\n', '    def formattree(self, tree, modname, parent=None):\n', '        """Produce HTML for a class tree as given by inspect.getclasstree()."""\n', "        result = ''\n", '        for entry in tree:\n', '            if type(entry) is type(()):\n', '                c, bases = entry\n', '                result = result + \'<dt><font face="helvetica, arial">\'\n', '                result = result + self.classlink(c, modname)\n', '                if bases and bases != (parent,):\n', '                    parents = []\n', '                    for base in bases:\n', '                        parents.append(self.classlink(base, modname))\n', "                    result = result + '(' + ', '.join(parents) + ')'\n", "                result = result + '\\n</font></dt>'\n", '            elif type(entry) is type([]):\n', "                result = result + '<dd>\\n%s</dd>\\n' % self.formattree(\n", '                    entry, modname, c)\n', "        return '<dl>\\n%s</dl>\\n' % result\n", '\n', '    def docmodule(self, object, name=None, mod=None, *ignored):\n', '        """Produce HTML documentation for a module object."""\n', '        name = object.__name__ # ignore the passed-in name\n', '        try:\n', '            all = object.__all__\n', '        except AttributeError:\n', '            all = None\n', "        parts = name.split('.')\n", '        links = []\n', '        for i in range(len(parts)-1):\n', '            links.append(\n', '                \'<a href="%s.html"><font color="#ffffff">%s</font></a>\' %\n', "                ('.'.join(parts[:i+1]), parts[i]))\n", "        linkedname = '.'.join(links + parts[-1:])\n", "        head = '<big><big><strong>%s</strong></big></big>' % linkedname\n", '        try:\n', '            path = inspect.getabsfile(object)\n', '            url = urllib.parse.quote(path)\n', '            filelink = self.filelink(url, path)\n', '        except TypeError:\n', "            filelink = '(built-in)'\n", '        info = []\n', "        if hasattr(object, '__version__'):\n", '            version = str(object.__version__)\n', "            if version[:11] == '


 + 'Revision: ' and version[-1:] == '


:\n", '                version = version[11:-1].strip()\n', "            info.append('version %s' % self.escape(version))\n", "        if hasattr(object, '__date__'):\n", '            info.append(self.escape(str(object.__date__)))\n', '        if info:\n', "            head = head + ' (%s)' % ', '.join(info)\n", '        docloc = self.getdocloc(object)\n', '        if docloc is not None:\n', '            docloc = \'<br><a href="%(docloc)s">Module Reference</a>\' % locals()\n', '        else:\n', "            docloc = ''\n", '        result = self.heading(\n', "            head, '#ffffff', '#7799ee',\n", '            \'<a href=".">index</a><br>\' + filelink + docloc)\n', '\n', '        modules = inspect.getmembers(object, inspect.ismodule)\n', '\n', '        classes, cdict = [], {}\n', '        for key, value in inspect.getmembers(object, _isclass):\n', '            # if __all__ exists, believe it.  Otherwise use old heuristic.\n', '            if (all is not None or\n', '                (inspect.getmodule(value) or object) is object):\n', '                if visiblename(key, all, object):\n', '                    classes.append((key, value))\n', "                    cdict[key] = cdict[value] = '#' + key\n", '        for key, value in classes:\n', '            for base in value.__bases__:\n', '                key, modname = base.__name__, base.__module__\n', '                module = sys.modules.get(modname)\n', '                if modname != name and module and hasattr(module, key):\n', '                    if getattr(module, key) is base:\n', '                        if not key in cdict:\n', "                            cdict[key] = cdict[base] = modname + '.html#' + key\n", '        funcs, fdict = [], {}\n', '        for key, value in inspect.getmembers(object, inspect.isroutine):\n', '            # if __all__ exists, believe it.  Otherwise use old heuristic.\n', '            if (all is not None or\n', '                inspect.isbuiltin(value) or inspect.getmodule(value) is object):\n', '                if visiblename(key, all, object):\n', '                    funcs.append((key, value))\n', "                    fdict[key] = '#-' + key\n", '                    if inspect.isfunction(value): fdict[value] = fdict[key]\n', '        data = []\n', '        for key, value in inspect.getmembers(object, isdata):\n', '            if visiblename(key, all, object):\n', '                data.append((key, value))\n', '\n', '        doc = self.markup(getdoc(object), self.preformat, fdict, cdict)\n', "        doc = doc and '<tt>%s</tt>' % doc\n", "        result = result + '<p>%s</p>\\n' % doc\n", '\n', "        if hasattr(object, '__path__'):\n", '            modpkgs = []\n', '            for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):\n', '                modpkgs.append((modname, name, ispkg, 0))\n', '            modpkgs.sort()\n', '            contents = self.multicolumn(modpkgs, self.modpkglink)\n', '            result = result + self.bigsection(\n', "                'Package Contents', '#ffffff', '#aa55cc', contents)\n", '        elif modules:\n', '            contents = self.multicolumn(\n', '                modules, lambda t: self.modulelink(t[1]))\n', '            result = result + self.bigsection(\n', "                'Modules', '#ffffff', '#aa55cc', contents)\n", '\n', '        if classes:\n', '            classlist = [value for (key, value) in classes]\n', '            contents = [\n', '                self.formattree(inspect.getclasstree(classlist, 1), name)]\n', '            for key, value in classes:\n', '                contents.append(self.document(value, key, name, fdict, cdict))\n', '            result = result + self.bigsection(\n', "                'Classes', '#ffffff', '#ee77aa', ' '.join(contents))\n", '        if funcs:\n', '            contents = []\n', '            for key, value in funcs:\n', '                contents.append(self.document(value, key, name, fdict, cdict))\n', '            result = result + self.bigsection(\n', "                'Functions', '#ffffff', '#eeaa77', ' '.join(contents))\n", '        if data:\n', '            contents = []\n', '            for key, value in data:\n', '                contents.append(self.document(value, key))\n', '            result = result + self.bigsection(\n', "                'Data', '#ffffff', '#55aa55', '<br>\\n'.join(contents))\n", "        if hasattr(object, '__author__'):\n", '            contents = self.markup(str(object.__author__), self.preformat)\n', '            result = result + self.bigsection(\n', "                'Author', '#ffffff', '#7799ee', contents)\n", "        if hasattr(object, '__credits__'):\n", '            contents = self.markup(str(object.__credits__), self.preformat)\n', '            result = result + self.bigsection(\n', "                'Credits', '#ffffff', '#7799ee', contents)\n", '\n', '        return result\n', '\n', '    def docclass(self, object, name=None, mod=None, funcs={}, classes={},\n', '                 *ignored):\n', '        """Produce HTML documentation for a class object."""\n', '        realname = object.__name__\n', '        name = name or realname\n', '        bases = object.__bases__\n', '\n', '        contents = []\n', '        push = contents.append\n', '\n', '        # Cute little class to pump out a horizontal rule between sections.\n', '        class HorizontalRule:\n', '            def __init__(self):\n', '                self.needone = 0\n', '            def maybe(self):\n', '                if self.needone:\n', "                    push('<hr>\\n')\n", '                self.needone = 1\n', '        hr = HorizontalRule()\n', '\n', '        # List the mro, if non-trivial.\n', '        mro = deque(inspect.getmro(object))\n', '        if len(mro) > 2:\n', '            hr.maybe()\n', "            push('<dl><dt>Method resolution order:</dt>\\n')\n", '            for base in mro:\n', "                push('<dd>%s</dd>\\n' % self.classlink(base,\n", '                                                      object.__module__))\n', "            push('</dl>\\n')\n", '\n', '        def spill(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    try:\n', '                        value = getattr(object, name)\n', '                    except Exception:\n', '                        # Some descriptors may meet a failure in their __get__.\n', '                        # (bug #1785)\n', '                        push(self.docdata(value, name, mod))\n', '                    else:\n', '                        push(self.document(value, name, mod,\n', '                                        funcs, classes, mdict, object))\n', "                    push('\\n')\n", '            return attrs\n', '\n', '        def spilldescriptors(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    push(self.docdata(value, name, mod))\n', '            return attrs\n', '\n', '        def spilldata(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    base = self.docother(getattr(object, name), name, mod)\n', '                    doc = getdoc(value)\n', '                    if not doc:\n', "                        push('<dl><dt>%s</dl>\\n' % base)\n", '                    else:\n', '                        doc = self.markup(getdoc(value), self.preformat,\n', '                                          funcs, classes, mdict)\n', "                        doc = '<dd><tt>%s</tt>' % doc\n", "                        push('<dl><dt>%s%s</dl>\\n' % (base, doc))\n", "                    push('\\n')\n", '            return attrs\n', '\n', '        attrs = [(name, kind, cls, value)\n', '                 for name, kind, cls, value in classify_class_attrs(object)\n', '                 if visiblename(name, obj=object)]\n', '\n', '        mdict = {}\n', '        for key, kind, homecls, value in attrs:\n', "            mdict[key] = anchor = '#' + name + '-' + key\n", '            try:\n', '                value = getattr(object, name)\n', '            except Exception:\n', '                # Some descriptors may meet a failure in their __get__.\n', '                # (bug #1785)\n', '                pass\n', '            try:\n', '                # The value may not be hashable (e.g., a data attr with\n', '                # a dict or list value).\n', '                mdict[value] = anchor\n', '            except TypeError:\n', '                pass\n', '\n', '        while attrs:\n', '            if mro:\n', '                thisclass = mro.popleft()\n', '            else:\n', '                thisclass = attrs[0][2]\n', '            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)\n', '\n', '            if object is not builtins.object and thisclass is builtins.object:\n', '                attrs = inherited\n', '                continue\n', '            elif thisclass is object:\n', "                tag = 'defined here'\n", '            else:\n', "                tag = 'inherited from %s' % self.classlink(thisclass,\n", '                                                           object.__module__)\n', "            tag += ':<br>\\n'\n", '\n', '            sort_attributes(attrs, object)\n', '\n', '            # Pump out the attrs, segregated by kind.\n', "            attrs = spill('Methods %s' % tag, attrs,\n", "                          lambda t: t[1] == 'method')\n", "            attrs = spill('Class methods %s' % tag, attrs,\n", "                          lambda t: t[1] == 'class method')\n", "            attrs = spill('Static methods %s' % tag, attrs,\n", "                          lambda t: t[1] == 'static method')\n", '            attrs = spilldescriptors("Readonly properties %s" % tag, attrs,\n', "                                     lambda t: t[1] == 'readonly property')\n", "            attrs = spilldescriptors('Data descriptors %s' % tag, attrs,\n", "                                     lambda t: t[1] == 'data descriptor')\n", "            attrs = spilldata('Data and other attributes %s' % tag, attrs,\n", "                              lambda t: t[1] == 'data')\n", '            assert attrs == []\n', '            attrs = inherited\n', '\n', "        contents = ''.join(contents)\n", '\n', '        if name == realname:\n', '            title = \'<a name="%s">class <strong>%s</strong></a>\' % (\n', '                name, realname)\n', '        else:\n', '            title = \'<strong>%s</strong> = <a name="%s">class %s</a>\' % (\n', '                name, name, realname)\n', '        if bases:\n', '            parents = []\n', '            for base in bases:\n', '                parents.append(self.classlink(base, object.__module__))\n', "            title = title + '(%s)' % ', '.join(parents)\n", '\n', "        decl = ''\n", '        try:\n', '            signature = inspect.signature(object)\n', '        except (ValueError, TypeError):\n', '            signature = None\n', '        if signature:\n', '            argspec = str(signature)\n', "            if argspec and argspec != '()':\n", "                decl = name + self.escape(argspec) + '\\n\\n'\n", '\n', '        doc = getdoc(object)\n', '        if decl:\n', "            doc = decl + (doc or '')\n", '        doc = self.markup(doc, self.preformat, funcs, classes, mdict)\n', "        doc = doc and '<tt>%s<br>&nbsp;</tt>' % doc\n", '\n', "        return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)\n", '\n', '    def formatvalue(self, object):\n', '        """Format an argument default value as text."""\n', "        return self.grey('=' + self.repr(object))\n", '\n', '    def docroutine(self, object, name=None, mod=None,\n', '                   funcs={}, classes={}, methods={}, cl=None):\n', '        """Produce HTML documentation for a function or method object."""\n', '        realname = object.__name__\n', '        name = name or realname\n', "        anchor = (cl and cl.__name__ or '') + '-' + name\n", "        note = ''\n", '        skipdocs = 0\n', '        if _is_bound_method(object):\n', '            imclass = object.__self__.__class__\n', '            if cl:\n', '                if imclass is not cl:\n', "                    note = ' from ' + self.classlink(imclass, mod)\n", '            else:\n', '                if object.__self__ is not None:\n', "                    note = ' method of %s instance' % self.classlink(\n", '                        object.__self__.__class__, mod)\n', '                else:\n', "                    note = ' unbound %s method' % self.classlink(imclass,mod)\n", '\n', '        if (inspect.iscoroutinefunction(object) or\n', '                inspect.isasyncgenfunction(object)):\n', "            asyncqualifier = 'async '\n", '        else:\n', "            asyncqualifier = ''\n", '\n', '        if name == realname:\n', '            title = \'<a name="%s"><strong>%s</strong></a>\' % (anchor, realname)\n', '        else:\n', '            if cl and inspect.getattr_static(cl, realname, []) is object:\n', '                reallink = \'<a href="#%s">%s</a>\' % (\n', "                    cl.__name__ + '-' + realname, realname)\n", '                skipdocs = 1\n', '            else:\n', '                reallink = realname\n', '            title = \'<a name="%s"><strong>%s</strong></a> = %s\' % (\n', '                anchor, name, reallink)\n', '        argspec = None\n', '        if inspect.isroutine(object):\n', '            try:\n', '                signature = inspect.signature(object)\n', '            except (ValueError, TypeError):\n', '                signature = None\n', '            if signature:\n', '                argspec = str(signature)\n', "                if realname == '<lambda>':\n", "                    title = '<strong>%s</strong> <em>lambda</em> ' % name\n", "                    # XXX lambda's won't usually have func_annotations['return']\n", "                    # since the syntax doesn't support but it is possible.\n", "                    # So removing parentheses isn't truly safe.\n", '                    argspec = argspec[1:-1] # remove parentheses\n', '        if not argspec:\n', "            argspec = '(...)'\n", '\n', '        decl = asyncqualifier + title + self.escape(argspec) + (note and\n', '               self.grey(\'<font face="helvetica, arial">%s</font>\' % note))\n', '\n', '        if skipdocs:\n', "            return '<dl><dt>%s</dt></dl>\\n' % decl\n", '        else:\n', '            doc = self.markup(\n', '                getdoc(object), self.preformat, funcs, classes, methods)\n', "            doc = doc and '<dd><tt>%s</tt></dd>' % doc\n", "            return '<dl><dt>%s</dt>%s</dl>\\n' % (decl, doc)\n", '\n', '    def docdata(self, object, name=None, mod=None, cl=None):\n', '        """Produce html documentation for a data descriptor."""\n', '        results = []\n', '        push = results.append\n', '\n', '        if name:\n', "            push('<dl><dt><strong>%s</strong></dt>\\n' % name)\n", '        doc = self.markup(getdoc(object), self.preformat)\n', '        if doc:\n', "            push('<dd><tt>%s</tt></dd>\\n' % doc)\n", "        push('</dl>\\n')\n", '\n', "        return ''.join(results)\n", '\n', '    docproperty = docdata\n', '\n', '    def docother(self, object, name=None, mod=None, *ignored):\n', '        """Produce HTML documentation for a data object."""\n', "        lhs = name and '<strong>%s</strong> = ' % name or ''\n", '        return lhs + self.repr(object)\n', '\n', '    def index(self, dir, shadowed=None):\n', '        """Generate an HTML index for a directory of modules."""\n', '        modpkgs = []\n', '        if shadowed is None: shadowed = {}\n', '        for importer, name, ispkg in pkgutil.iter_modules([dir]):\n', '            if any((0xD800 <= ord(ch) <= 0xDFFF) for ch in name):\n', '                # ignore a module if its name contains a surrogate character\n', '                continue\n', "            modpkgs.append((name, '', ispkg, name in shadowed))\n", '            shadowed[name] = 1\n', '\n', '        modpkgs.sort()\n', '        contents = self.multicolumn(modpkgs, self.modpkglink)\n', "        return self.bigsection(dir, '#ffffff', '#ee77aa', contents)\n", '\n', '# -------------------------------------------- text documentation generator\n', '\n', 'class TextRepr(Repr):\n', '    """Class for safely making a text representation of a Python object."""\n', '    def __init__(self):\n', '        Repr.__init__(self)\n', '        self.maxlist = self.maxtuple = 20\n', '        self.maxdict = 10\n', '        self.maxstring = self.maxother = 100\n', '\n', '    def repr1(self, x, level):\n', "        if hasattr(type(x), '__name__'):\n", "            methodname = 'repr_' + '_'.join(type(x).__name__.split())\n", '            if hasattr(self, methodname):\n', '                return getattr(self, methodname)(x, level)\n', '        return cram(stripid(repr(x)), self.maxother)\n', '\n', '    def repr_string(self, x, level):\n', '        test = cram(x, self.maxstring)\n', '        testrepr = repr(test)\n', "        if '\\\\' in test and '\\\\' not in replace(testrepr, r'\\\\', ''):\n", '            # Backslashes are only literal in the string and are never\n', '            # needed to make any special characters, so show a raw string.\n', "            return 'r' + testrepr[0] + test + testrepr[0]\n", '        return testrepr\n', '\n', '    repr_str = repr_string\n', '\n', '    def repr_instance(self, x, level):\n', '        try:\n', '            return cram(stripid(repr(x)), self.maxstring)\n', '        except:\n', "            return '<%s instance>' % x.__class__.__name__\n", '\n', 'class TextDoc(Doc):\n', '    """Formatter class for text documentation."""\n', '\n', '    # ------------------------------------------- text formatting utilities\n', '\n', '    _repr_instance = TextRepr()\n', '    repr = _repr_instance.repr\n', '\n', '    def bold(self, text):\n', '        """Format a string in bold by overstriking."""\n', "        return ''.join(ch + '\\b' + ch for ch in text)\n", '\n', "    def indent(self, text, prefix='    '):\n", '        """Indent text by prepending a given prefix to each line."""\n', "        if not text: return ''\n", "        lines = [prefix + line for line in text.split('\\n')]\n", '        if lines: lines[-1] = lines[-1].rstrip()\n', "        return '\\n'.join(lines)\n", '\n', '    def section(self, title, contents):\n', '        """Format a section with a given heading."""\n', '        clean_contents = self.indent(contents).rstrip()\n', "        return self.bold(title) + '\\n' + clean_contents + '\\n\\n'\n", '\n', '    # ---------------------------------------------- type-specific routines\n', '\n', "    def formattree(self, tree, modname, parent=None, prefix=''):\n", '        """Render in text a class tree as returned by inspect.getclasstree()."""\n', "        result = ''\n", '        for entry in tree:\n', '            if type(entry) is type(()):\n', '                c, bases = entry\n', '                result = result + prefix + classname(c, modname)\n', '                if bases and bases != (parent,):\n', '                    parents = (classname(c, modname) for c in bases)\n', "                    result = result + '(%s)' % ', '.join(parents)\n", "                result = result + '\\n'\n", '            elif type(entry) is type([]):\n', '                result = result + self.formattree(\n', "                    entry, modname, c, prefix + '    ')\n", '        return result\n', '\n', '    def docmodule(self, object, name=None, mod=None):\n', '        """Produce text documentation for a given module object."""\n', '        name = object.__name__ # ignore the passed-in name\n', '        synop, desc = splitdoc(getdoc(object))\n', "        result = self.section('NAME', name + (synop and ' - ' + synop))\n", "        all = getattr(object, '__all__', None)\n", '        docloc = self.getdocloc(object)\n', '        if docloc is not None:\n', '            result = result + self.section(\'MODULE REFERENCE\', docloc + """\n', '\n', 'The following documentation is automatically generated from the Python\n', 'source files.  It may be incomplete, incorrect or include features that\n', 'are considered implementation detail and may vary between Python\n', 'implementations.  When in doubt, consult the module reference at the\n', 'location listed above.\n', '""")\n', '\n', '        if desc:\n', "            result = result + self.section('DESCRIPTION', desc)\n", '\n', '        classes = []\n', '        for key, value in inspect.getmembers(object, _isclass):\n', '            # if __all__ exists, believe it.  Otherwise use old heuristic.\n', '            if (all is not None\n', '                or (inspect.getmodule(value) or object) is object):\n', '                if visiblename(key, all, object):\n', '                    classes.append((key, value))\n', '        funcs = []\n', '        for key, value in inspect.getmembers(object, inspect.isroutine):\n', '            # if __all__ exists, believe it.  Otherwise use old heuristic.\n', '            if (all is not None or\n', '                inspect.isbuiltin(value) or inspect.getmodule(value) is object):\n', '                if visiblename(key, all, object):\n', '                    funcs.append((key, value))\n', '        data = []\n', '        for key, value in inspect.getmembers(object, isdata):\n', '            if visiblename(key, all, object):\n', '                data.append((key, value))\n', '\n', '        modpkgs = []\n', '        modpkgs_names = set()\n', "        if hasattr(object, '__path__'):\n", '            for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):\n', '                modpkgs_names.add(modname)\n', '                if ispkg:\n', "                    modpkgs.append(modname + ' (package)')\n", '                else:\n', '                    modpkgs.append(modname)\n', '\n', '            modpkgs.sort()\n', '            result = result + self.section(\n', "                'PACKAGE CONTENTS', '\\n'.join(modpkgs))\n", '\n', '        # Detect submodules as sometimes created by C extensions\n', '        submodules = []\n', '        for key, value in inspect.getmembers(object, inspect.ismodule):\n', "            if value.__name__.startswith(name + '.') and key not in modpkgs_names:\n", '                submodules.append(key)\n', '        if submodules:\n', '            submodules.sort()\n', '            result = result + self.section(\n', "                'SUBMODULES', '\\n'.join(submodules))\n", '\n', '        if classes:\n', '            classlist = [value for key, value in classes]\n', '            contents = [self.formattree(\n', '                inspect.getclasstree(classlist, 1), name)]\n', '            for key, value in classes:\n', '                contents.append(self.document(value, key, name))\n', "            result = result + self.section('CLASSES', '\\n'.join(contents))\n", '\n', '        if funcs:\n', '            contents = []\n', '            for key, value in funcs:\n', '                contents.append(self.document(value, key, name))\n', "            result = result + self.section('FUNCTIONS', '\\n'.join(contents))\n", '\n', '        if data:\n', '            contents = []\n', '            for key, value in data:\n', '                contents.append(self.docother(value, key, name, maxlen=70))\n', "            result = result + self.section('DATA', '\\n'.join(contents))\n", '\n', "        if hasattr(object, '__version__'):\n", '            version = str(object.__version__)\n', "            if version[:11] == '


 + 'Revision: ' and version[-1:] == '


:\n", '                version = version[11:-1].strip()\n', "            result = result + self.section('VERSION', version)\n", "        if hasattr(object, '__date__'):\n", "            result = result + self.section('DATE', str(object.__date__))\n", "        if hasattr(object, '__author__'):\n", "            result = result + self.section('AUTHOR', str(object.__author__))\n", "        if hasattr(object, '__credits__'):\n", "            result = result + self.section('CREDITS', str(object.__credits__))\n", '        try:\n', '            file = inspect.getabsfile(object)\n', '        except TypeError:\n', "            file = '(built-in)'\n", "        result = result + self.section('FILE', file)\n", '        return result\n', '\n', '    def docclass(self, object, name=None, mod=None, *ignored):\n', '        """Produce text documentation for a given class object."""\n', '        realname = object.__name__\n', '        name = name or realname\n', '        bases = object.__bases__\n', '\n', '        def makename(c, m=object.__module__):\n', '            return classname(c, m)\n', '\n', '        if name == realname:\n', "            title = 'class ' + self.bold(realname)\n", '        else:\n', "            title = self.bold(name) + ' = class ' + realname\n", '        if bases:\n', '            parents = map(makename, bases)\n', "            title = title + '(%s)' % ', '.join(parents)\n", '\n', '        contents = []\n', '        push = contents.append\n', '\n', '        try:\n', '            signature = inspect.signature(object)\n', '        except (ValueError, TypeError):\n', '            signature = None\n', '        if signature:\n', '            argspec = str(signature)\n', "            if argspec and argspec != '()':\n", "                push(name + argspec + '\\n')\n", '\n', '        doc = getdoc(object)\n', '        if doc:\n', "            push(doc + '\\n')\n", '\n', '        # List the mro, if non-trivial.\n', '        mro = deque(inspect.getmro(object))\n', '        if len(mro) > 2:\n', '            push("Method resolution order:")\n', '            for base in mro:\n', "                push('    ' + makename(base))\n", "            push('')\n", '\n', '        # List the built-in subclasses, if any:\n', '        subclasses = sorted(\n', '            (str(cls.__name__) for cls in type.__subclasses__(object)\n', '             if not cls.__name__.startswith("_") and cls.__module__ == "builtins"),\n', '            key=str.lower\n', '        )\n', '        no_of_subclasses = len(subclasses)\n', '        MAX_SUBCLASSES_TO_DISPLAY = 4\n', '        if subclasses:\n', '            push("Built-in subclasses:")\n', '            for subclassname in subclasses[:MAX_SUBCLASSES_TO_DISPLAY]:\n', "                push('    ' + subclassname)\n", '            if no_of_subclasses > MAX_SUBCLASSES_TO_DISPLAY:\n', "                push('    ... and ' +\n", '                     str(no_of_subclasses - MAX_SUBCLASSES_TO_DISPLAY) +\n', "                     ' other subclasses')\n", "            push('')\n", '\n', '        # Cute little class to pump out a horizontal rule between sections.\n', '        class HorizontalRule:\n', '            def __init__(self):\n', '                self.needone = 0\n', '            def maybe(self):\n', '                if self.needone:\n', "                    push('-' * 70)\n", '                self.needone = 1\n', '        hr = HorizontalRule()\n', '\n', '        def spill(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    try:\n', '                        value = getattr(object, name)\n', '                    except Exception:\n', '                        # Some descriptors may meet a failure in their __get__.\n', '                        # (bug #1785)\n', '                        push(self.docdata(value, name, mod))\n', '                    else:\n', '                        push(self.document(value,\n', '                                        name, mod, object))\n', '            return attrs\n', '\n', '        def spilldescriptors(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    push(self.docdata(value, name, mod))\n', '            return attrs\n', '\n', '        def spilldata(msg, attrs, predicate):\n', '            ok, attrs = _split_list(attrs, predicate)\n', '            if ok:\n', '                hr.maybe()\n', '                push(msg)\n', '                for name, kind, homecls, value in ok:\n', '                    doc = getdoc(value)\n', '                    try:\n', '                        obj = getattr(object, name)\n', '                    except AttributeError:\n', '                        obj = homecls.__dict__[name]\n', '                    push(self.docother(obj, name, mod, maxlen=70, doc=doc) +\n', "                         '\\n')\n", '            return attrs\n', '\n', '        attrs = [(name, kind, cls, value)\n', '                 for name, kind, cls, value in classify_class_attrs(object)\n', '                 if visiblename(name, obj=object)]\n', '\n', '        while attrs:\n', '            if mro:\n', '                thisclass = mro.popleft()\n', '            else:\n', '                thisclass = attrs[0][2]\n', '            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)\n', '\n', '            if object is not builtins.object and thisclass is builtins.object:\n', '                attrs = inherited\n', '                continue\n', '            elif thisclass is object:\n', '                tag = "defined here"\n', '            else:\n', '                tag = "inherited from %s" % classname(thisclass,\n', '                                                      object.__module__)\n', '\n', '            sort_attributes(attrs, object)\n', '\n', '            # Pump out the attrs, segregated by kind.\n', '            attrs = spill("Methods %s:\\n" % tag, attrs,\n', "                          lambda t: t[1] == 'method')\n", '            attrs = spill("Class methods %s:\\n" % tag, attrs,\n', "                          lambda t: t[1] == 'class method')\n", '            attrs = spill("Static methods %s:\\n" % tag, attrs,\n', "                          lambda t: t[1] == 'static method')\n", '            attrs = spilldescriptors("Readonly properties %s:\\n" % tag, attrs,\n', "                                     lambda t: t[1] == 'readonly property')\n", '            attrs = spilldescriptors("Data descriptors %s:\\n" % tag, attrs,\n', "                                     lambda t: t[1] == 'data descriptor')\n", '            attrs = spilldata("Data and other attributes %s:\\n" % tag, attrs,\n', "                              lambda t: t[1] == 'data')\n", '\n', '            assert attrs == []\n', '            attrs = inherited\n', '\n', "        contents = '\\n'.join(contents)\n", '        if not contents:\n', "            return title + '\\n'\n", "        return title + '\\n' + self.indent(contents.rstrip(), ' |  ') + '\\n'\n", '\n', '    def formatvalue(self, object):\n', '        """Format an argument default value as text."""\n', "        return '=' + self.repr(object)\n", '\n', '    def docroutine(self, object, name=None, mod=None, cl=None):\n', '        """Produce text documentation for a function or method object."""\n', '        realname = object.__name__\n', '        name = name or realname\n', "        note = ''\n", '        skipdocs = 0\n', '        if _is_bound_method(object):\n', '            imclass = object.__self__.__class__\n', '            if cl:\n', '                if imclass is not cl:\n', "                    note = ' from ' + classname(imclass, mod)\n", '            else:\n', '                if object.__self__ is not None:\n', "                    note = ' method of %s instance' % classname(\n", '                        object.__self__.__class__, mod)\n', '                else:\n', "                    note = ' unbound %s method' % classname(imclass,mod)\n", '\n', '        if (inspect.iscoroutinefunction(object) or\n', '                inspect.isasyncgenfunction(object)):\n', "            asyncqualifier = 'async '\n", '        else:\n', "            asyncqualifier = ''\n", '\n', '        if name == realname:\n', '            title = self.bold(realname)\n', '        else:\n', '            if cl and inspect.getattr_static(cl, realname, []) is object:\n', '                skipdocs = 1\n', "            title = self.bold(name) + ' = ' + realname\n", '        argspec = None\n', '\n', '        if inspect.isroutine(object):\n', '            try:\n', '                signature = inspect.signature(object)\n', '            except (ValueError, TypeError):\n', '                signature = None\n', '            if signature:\n', '                argspec = str(signature)\n', "                if realname == '<lambda>':\n", "                    title = self.bold(name) + ' lambda '\n", "                    # XXX lambda's won't usually have func_annotations['return']\n", "                    # since the syntax doesn't support but it is possible.\n", "                    # So removing parentheses isn't truly safe.\n", '                    argspec = argspec[1:-1] # remove parentheses\n', '        if not argspec:\n', "            argspec = '(...)'\n", '        decl = asyncqualifier + title + argspec + note\n', '\n', '        if skipdocs:\n', "            return decl + '\\n'\n", '        else:\n', "            doc = getdoc(object) or ''\n", "            return decl + '\\n' + (doc and self.indent(doc).rstrip() + '\\n')\n", '\n', '    def docdata(self, object, name=None, mod=None, cl=None):\n', '        """Produce text documentation for a data descriptor."""\n', '        results = []\n', '        push = results.append\n', '\n', '        if name:\n', '            push(self.bold(name))\n', "            push('\\n')\n", "        doc = getdoc(object) or ''\n", '        if doc:\n', '            push(self.indent(doc))\n', "            push('\\n')\n", "        return ''.join(results)\n", '\n', '    docproperty = docdata\n', '\n', '    def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None):\n', '        """Produce text documentation for a data object."""\n', '        repr = self.repr(object)\n', '        if maxlen:\n', "            line = (name and name + ' = ' or '') + repr\n", '            chop = maxlen - len(line)\n', "            if chop < 0: repr = repr[:chop] + '...'\n", "        line = (name and self.bold(name) + ' = ' or '') + repr\n", '        if not doc:\n', '            doc = getdoc(object)\n', '        if doc:\n', "            line += '\\n' + self.indent(str(doc)) + '\\n'\n", '        return line\n', '\n', 'class _PlainTextDoc(TextDoc):\n', '    """Subclass of TextDoc which overrides string styling"""\n', '    def bold(self, text):\n', '        return text\n', '\n', '# --------------------------------------------------------- user interfaces\n', '\n', 'def pager(text):\n', '    """The first time this is called, determine what kind of pager to use."""\n', '    global pager\n', '    pager = getpager()\n', '    pager(text)\n', '\n', 'def getpager():\n', '    """Decide what method to use for paging through text."""\n', '    if not hasattr(sys.stdin, "isatty"):\n', '        return plainpager\n', '    if not hasattr(sys.stdout, "isatty"):\n', '        return plainpager\n', '    if not sys.stdin.isatty() or not sys.stdout.isatty():\n', '        return plainpager\n', "    use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER')\n", '    if use_pager:\n', "        if sys.platform == 'win32': # pipes completely broken in Windows\n", '            return lambda text: tempfilepager(plain(text), use_pager)\n', "        elif os.environ.get('TERM') in ('dumb', 'emacs'):\n", '            return lambda text: pipepager(plain(text), use_pager)\n', '        else:\n', '            return lambda text: pipepager(text, use_pager)\n', "    if os.environ.get('TERM') in ('dumb', 'emacs'):\n", '        return plainpager\n', "    if sys.platform == 'win32':\n", "        return lambda text: tempfilepager(plain(text), 'more <')\n", "    if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:\n", "        return lambda text: pipepager(text, 'less')\n", '\n', '    import tempfile\n', '    (fd, filename) = tempfile.mkstemp()\n', '    os.close(fd)\n', '    try:\n', '        if hasattr(os, \'system\') and os.system(\'more "%s"\' % filename) == 0:\n', "            return lambda text: pipepager(text, 'more')\n", '        else:\n', '            return ttypager\n', '    finally:\n', '        os.unlink(filename)\n', '\n', 'def plain(text):\n', '    """Remove boldface formatting from text."""\n', "    return re.sub('.\\b', '', text)\n", '\n', 'def pipepager(text, cmd):\n', '    """Page through text by feeding it to another program."""\n', '    import subprocess\n', '    proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,\n', "                            errors='backslashreplace')\n", '    try:\n', '        with proc.stdin as pipe:\n', '            try:\n', '                pipe.write(text)\n', '            except KeyboardInterrupt:\n', "                # We've hereby abandoned whatever text hasn't been written,\n", '                # but the pager is still in control of the terminal.\n', '                pass\n', '    except OSError:\n', '        pass # Ignore broken pipes caused by quitting the pager program.\n', '    while True:\n', '        try:\n', '            proc.wait()\n', '            break\n', '        except KeyboardInterrupt:\n', '            # Ignore ctl-c like the pager itself does.  Otherwise the pager is\n', '            # left running and the terminal is in raw mode and unusable.\n', '            pass\n', '\n', 'def tempfilepager(text, cmd):\n', '    """Page through text by invoking a program on a temporary file."""\n', '    import tempfile\n', '    with tempfile.TemporaryDirectory() as tempdir:\n', "        filename = os.path.join(tempdir, 'pydoc.out')\n", "        with open(filename, 'w', errors='backslashreplace',\n", '                  encoding=os.device_encoding(0) if\n', "                  sys.platform == 'win32' else None\n", '                  ) as file:\n', '            file.write(text)\n', '        os.system(cmd + \' "\' + filename + \'"\')\n', '\n', 'def _escape_stdout(text):\n', '    # Escape non-encodable characters to avoid encoding errors later\n', "    encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'\n", "    return text.encode(encoding, 'backslashreplace').decode(encoding)\n", '\n', 'def ttypager(text):\n', '    """Page through text on a text terminal."""\n', "    lines = plain(_escape_stdout(text)).split('\\n')\n", '    try:\n', '        import tty\n', '        fd = sys.stdin.fileno()\n', '        old = tty.tcgetattr(fd)\n', '        tty.setcbreak(fd)\n', '        getchar = lambda: sys.stdin.read(1)\n', '    except (ImportError, AttributeError, io.UnsupportedOperation):\n', '        tty = None\n', '        getchar = lambda: sys.stdin.readline()[:-1][:1]\n', '\n', '    try:\n', '        try:\n', "            h = int(os.environ.get('LINES', 0))\n", '        except ValueError:\n', '            h = 0\n', '        if h <= 1:\n', '            h = 25\n', '        r = inc = h - 1\n', "        sys.stdout.write('\\n'.join(lines[:inc]) + '\\n')\n", '        while lines[r:]:\n', "            sys.stdout.write('-- more --')\n", '            sys.stdout.flush()\n', '            c = getchar()\n', '\n', "            if c in ('q', 'Q'):\n", "                sys.stdout.write('\\r          \\r')\n", '                break\n', "            elif c in ('\\r', '\\n'):\n", "                sys.stdout.write('\\r          \\r' + lines[r] + '\\n')\n", '                r = r + 1\n', '                continue\n', "            if c in ('b', 'B', '\\x1b'):\n", '                r = r - inc - inc\n', '                if r < 0: r = 0\n', "            sys.stdout.write('\\n' + '\\n'.join(lines[r:r+inc]) + '\\n')\n", '            r = r + inc\n', '\n', '    finally:\n', '        if tty:\n', '            tty.tcsetattr(fd, tty.TCSAFLUSH, old)\n', '\n', 'def plainpager(text):\n', '    """Simply print unformatted text.  This is the ultimate fallback."""\n', '    sys.stdout.write(plain(_escape_stdout(text)))\n', '\n', 'def describe(thing):\n', '    """Produce a short description of the given thing."""\n', '    if inspect.ismodule(thing):\n', '        if thing.__name__ in sys.builtin_module_names:\n', "            return 'built-in module ' + thing.__name__\n", "        if hasattr(thing, '__path__'):\n", "            return 'package ' + thing.__name__\n", '        else:\n', "            return 'module ' + thing.__name__\n", '    if inspect.isbuiltin(thing):\n', "        return 'built-in function ' + thing.__name__\n", '    if inspect.isgetsetdescriptor(thing):\n', "        return 'getset descriptor %s.%s.%s' % (\n", '            thing.__objclass__.__module__, thing.__objclass__.__name__,\n', '            thing.__name__)\n', '    if inspect.ismemberdescriptor(thing):\n', "        return 'member descriptor %s.%s.%s' % (\n", '            thing.__objclass__.__module__, thing.__objclass__.__name__,\n', '            thing.__name__)\n', '    if _isclass(thing):\n', "        return 'class ' + thing.__name__\n", '    if inspect.isfunction(thing):\n', "        return 'function ' + thing.__name__\n", '    if inspect.ismethod(thing):\n', "        return 'method ' + thing.__name__\n", '    return type(thing).__name__\n', '\n', 'def locate(path, forceload=0):\n', '    """Locate an object by name or dotted path, importing as necessary."""\n', "    parts = [part for part in path.split('.') if part]\n", '    module, n = None, 0\n', '    while n < len(parts):\n', "        nextmodule = safeimport('.'.join(parts[:n+1]), forceload)\n", '        if nextmodule: module, n = nextmodule, n + 1\n', '        else: break\n', '    if module:\n', '        object = module\n', '    else:\n', '        object = builtins\n', '    for part in parts[n:]:\n', '        try:\n', '            object = getattr(object, part)\n', '        except AttributeError:\n', '            return None\n', '    return object\n', '\n', '# --------------------------------------- interactive interpreter interface\n', '\n', 'text = TextDoc()\n', 'plaintext = _PlainTextDoc()\n', 'html = HTMLDoc()\n', '\n', 'def resolve(thing, forceload=0):\n', '    """Given an object or a path to an object, get the object and its name."""\n', '    if isinstance(thing, str):\n', '        object = locate(thing, forceload)\n', '        if object is None:\n', "            raise ImportError('''\\\n", 'No Python documentation found for %r.\n', 'Use help() to get the interactive help utility.\n', "Use help(str) for help on the str class.''' % thing)\n", '        return object, thing\n', '    else:\n', "        name = getattr(thing, '__name__', None)\n", '        return thing, name if isinstance(name, str) else None\n', '\n', "def render_doc(thing, title='Python Library Documentation: %s', forceload=0,\n", '        renderer=None):\n', '    """Render text documentation, given an object or a path to an object."""\n', '    if renderer is None:\n', '        renderer = text\n', '    object, name = resolve(thing, forceload)\n', '    desc = describe(object)\n', '    module = inspect.getmodule(object)\n', "    if name and '.' in name:\n", "        desc += ' in ' + name[:name.rfind('.')]\n", '    elif module and module is not object:\n', "        desc += ' in module ' + module.__name__\n", '\n', '    if not (inspect.ismodule(object) or\n', '              _isclass(object) or\n', '              inspect.isroutine(object) or\n', '              inspect.isdatadescriptor(object) or\n', '              _getdoc(object)):\n', '        # If the passed object is a piece of data or an instance,\n', '        # document its available methods instead of its value.\n', "        if hasattr(object, '__origin__'):\n", '            object = object.__origin__\n', '        else:\n', '            object = type(object)\n', "            desc += ' object'\n", "    return title % desc + '\\n\\n' + renderer.document(object, name)\n", '\n', "def doc(thing, title='Python Library Documentation: %s', forceload=0,\n", '        output=None):\n', '    """Display text documentation, given an object or a path to an object."""\n', '    try:\n', '        if output is None:\n', '            pager(render_doc(thing, title, forceload))\n', '        else:\n', '            output.write(render_doc(thing, title, forceload, plaintext))\n', '    except (ImportError, ErrorDuringImport) as value:\n', '        print(value)\n', '\n', 'def writedoc(thing, forceload=0):\n', '    """Write HTML documentation to a file in the current directory."""\n', '    try:\n', '        object, name = resolve(thing, forceload)\n', '        page = html.page(describe(object), html.document(object, name))\n', "        with open(name + '.html', 'w', encoding='utf-8') as file:\n", '            file.write(page)\n', "        print('wrote', name + '.html')\n", '    except (ImportError, ErrorDuringImport) as value:\n', '        print(value)\n', '\n', "def writedocs(dir, pkgpath='', done=None):\n", '    """Write out HTML documentation for all modules in a directory tree."""\n', '    if done is None: done = {}\n', '    for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath):\n', '        writedoc(modname)\n', '    return\n', '\n', 'class Helper:\n', '\n', '    # These dictionaries map a topic name to either an alias, or a tuple\n', '    # (label, seealso-items).  The "label" is the label of the corresponding\n', '    # section in the .rst file under Doc/ and an index into the dictionary\n', '    # in pydoc_data/topics.py.\n', '    #\n', '    # CAUTION: if you change one of these dictionaries, be sure to adapt the\n', '    #          list of needed labels in Doc/tools/extensions/pyspecific.py and\n', '    #          regenerate the pydoc_data/topics.py file by running\n', '    #              make pydoc-topics\n', '    #          in Doc/ and copying the output file into the Lib/ directory.\n', '\n', '    keywords = {\n', "        'False': '',\n", "        'None': '',\n", "        'True': '',\n", "        'and': 'BOOLEAN',\n", "        'as': 'with',\n", "        'assert': ('assert', ''),\n", "        'async': ('async', ''),\n", "        'await': ('await', ''),\n", "        'break': ('break', 'while for'),\n", "        'class': ('class', 'CLASSES SPECIALMETHODS'),\n", "        'continue': ('continue', 'while for'),\n", "        'def': ('function', ''),\n", "        'del': ('del', 'BASICMETHODS'),\n", "        'elif': 'if',\n", "        'else': ('else', 'while for'),\n", "        'except': 'try',\n", "        'finally': 'try',\n", "        'for': ('for', 'break continue while'),\n", "        'from': 'import',\n", "        'global': ('global', 'nonlocal NAMESPACES'),\n", "        'if': ('if', 'TRUTHVALUE'),\n", "        'import': ('import', 'MODULES'),\n", "        'in': ('in', 'SEQUENCEMETHODS'),\n", "        'is': 'COMPARISON',\n", "        'lambda': ('lambda', 'FUNCTIONS'),\n", "        'nonlocal': ('nonlocal', 'global NAMESPACES'),\n", "        'not': 'BOOLEAN',\n", "        'or': 'BOOLEAN',\n", "        'pass': ('pass', ''),\n", "        'raise': ('raise', 'EXCEPTIONS'),\n", "        'return': ('return', 'FUNCTIONS'),\n", "        'try': ('try', 'EXCEPTIONS'),\n", "        'while': ('while', 'break continue if TRUTHVALUE'),\n", "        'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),\n", "        'yield': ('yield', ''),\n", '    }\n', '    # Either add symbols to this dictionary or to the symbols dictionary\n', '    # directly: Whichever is easier. They are merged later.\n', '    _strprefixes = [p + q for p in (\'b\', \'f\', \'r\', \'u\') for q in ("\'", \'"\')]\n', '    _symbols_inverse = {\n', '        \'STRINGS\' : ("\'", "\'\'\'", \'"\', \'"""\', *_strprefixes),\n', "        'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',\n", "                       '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),\n", "        'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),\n", "        'UNARY' : ('-', '~'),\n", "        'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',\n", "                                '^=', '<<=', '>>=', '**=', '//='),\n", "        'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),\n", "        'COMPLEX' : ('j', 'J')\n", '    }\n', '    symbols = {\n', "        '%': 'OPERATORS FORMATTING',\n", "        '**': 'POWER',\n", "        ',': 'TUPLES LISTS FUNCTIONS',\n", "        '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',\n", "        '...': 'ELLIPSIS',\n", "        ':': 'SLICINGS DICTIONARYLITERALS',\n", "        '@': 'def class',\n", "        '\\\\': 'STRINGS',\n", "        '_': 'PRIVATENAMES',\n", "        '__': 'PRIVATENAMES SPECIALMETHODS',\n", "        '`': 'BACKQUOTES',\n", "        '(': 'TUPLES FUNCTIONS CALLS',\n", "        ')': 'TUPLES FUNCTIONS CALLS',\n", "        '[': 'LISTS SUBSCRIPTS SLICINGS',\n", "        ']': 'LISTS SUBSCRIPTS SLICINGS'\n", '    }\n', '    for topic, symbols_ in _symbols_inverse.items():\n', '        for symbol in symbols_:\n', '            topics = symbols.get(symbol, topic)\n', '            if topic not in topics:\n', "                topics = topics + ' ' + topic\n", '            symbols[symbol] = topics\n', '\n', '    topics = {\n', "        'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '\n", "                  'FUNCTIONS CLASSES MODULES FILES inspect'),\n", "        'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS '\n", "                    'FORMATTING TYPES'),\n", "        'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),\n", "        'FORMATTING': ('formatstrings', 'OPERATORS'),\n", "        'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '\n", "                    'FORMATTING TYPES'),\n", "        'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),\n", "        'INTEGER': ('integers', 'int range'),\n", "        'FLOAT': ('floating', 'float math'),\n", "        'COMPLEX': ('imaginary', 'complex cmath'),\n", "        'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING range LISTS'),\n", "        'MAPPINGS': 'DICTIONARIES',\n", "        'FUNCTIONS': ('typesfunctions', 'def TYPES'),\n", "        'METHODS': ('typesmethods', 'class def CLASSES TYPES'),\n", "        'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),\n", "        'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),\n", "        'FRAMEOBJECTS': 'TYPES',\n", "        'TRACEBACKS': 'TYPES',\n", "        'NONE': ('bltin-null-object', ''),\n", "        'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),\n", "        'SPECIALATTRIBUTES': ('specialattrs', ''),\n", "        'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),\n", "        'MODULES': ('typesmodules', 'import'),\n", "        'PACKAGES': 'import',\n", "        'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '\n", "                        'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '\n", "                        'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '\n", "                        'LISTS DICTIONARIES'),\n", "        'OPERATORS': 'EXPRESSIONS',\n", "        'PRECEDENCE': 'EXPRESSIONS',\n", "        'OBJECTS': ('objects', 'TYPES'),\n", "        'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '\n", "                           'CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS '\n", "                           'NUMBERMETHODS CLASSES'),\n", "        'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'),\n", "        'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),\n", "        'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),\n", "        'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS '\n", "                             'SPECIALMETHODS'),\n", "        'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),\n", "        'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '\n", "                          'SPECIALMETHODS'),\n", "        'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),\n", "        'NAMESPACES': ('naming', 'global nonlocal ASSIGNMENT DELETION DYNAMICFEATURES'),\n", "        'DYNAMICFEATURES': ('dynamic-features', ''),\n", "        'SCOPING': 'NAMESPACES',\n", "        'FRAMES': 'NAMESPACES',\n", "        'EXCEPTIONS': ('exceptions', 'try except finally raise'),\n", "        'CONVERSIONS': ('conversions', ''),\n", "        'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),\n", "        'SPECIALIDENTIFIERS': ('id-classes', ''),\n", "        'PRIVATENAMES': ('atom-identifiers', ''),\n", "        'LITERALS': ('atom-literals', 'STRINGS NUMBERS TUPLELITERALS '\n", "                     'LISTLITERALS DICTIONARYLITERALS'),\n", "        'TUPLES': 'SEQUENCES',\n", "        'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),\n", "        'LISTS': ('typesseq-mutable', 'LISTLITERALS'),\n", "        'LISTLITERALS': ('lists', 'LISTS LITERALS'),\n", "        'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),\n", "        'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),\n", "        'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'),\n", "        'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS'),\n", "        'SLICINGS': ('slicings', 'SEQUENCEMETHODS'),\n", "        'CALLS': ('calls', 'EXPRESSIONS'),\n", "        'POWER': ('power', 'EXPRESSIONS'),\n", "        'UNARY': ('unary', 'EXPRESSIONS'),\n", "        'BINARY': ('binary', 'EXPRESSIONS'),\n", "        'SHIFTING': ('shifting', 'EXPRESSIONS'),\n", "        'BITWISE': ('bitwise', 'EXPRESSIONS'),\n", "        'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),\n", "        'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),\n", "        'ASSERTION': 'assert',\n", "        'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),\n", "        'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),\n", "        'DELETION': 'del',\n", "        'RETURNING': 'return',\n", "        'IMPORTING': 'import',\n", "        'CONDITIONAL': 'if',\n", "        'LOOPING': ('compound', 'for while break continue'),\n", "        'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),\n", "        'DEBUGGING': ('debugger', 'pdb'),\n", "        'CONTEXTMANAGERS': ('context-managers', 'with'),\n", '    }\n', '\n', '    def __init__(self, input=None, output=None):\n', '        self._input = input\n', '        self._output = output\n', '\n', '    @property\n', '    def input(self):\n', '        return self._input or sys.stdin\n', '\n', '    @property\n', '    def output(self):\n', '        return self._output or sys.stdout\n', '\n', '    def __repr__(self):\n', "        if inspect.stack()[1][3] == '?':\n", '            self()\n', "            return ''\n", "        return '<%s.%s instance>' % (self.__class__.__module__,\n", '                                     self.__class__.__qualname__)\n', '\n', '    _GoInteractive = object()\n', '    def __call__(self, request=_GoInteractive):\n', '        if request is not self._GoInteractive:\n', '            self.help(request)\n', '        else:\n', '            self.intro()\n', '            self.interact()\n', "            self.output.write('''\n", 'You are now leaving help and returning to the Python interpreter.\n', 'If you want to ask for help on a particular object directly from the\n', 'interpreter, you can type "help(object)".  Executing "help(\'string\')"\n', 'has the same effect as typing a particular string at the help> prompt.\n', "''')\n", '\n', '    def interact(self):\n', "        self.output.write('\\n')\n", '        while True:\n', '            try:\n', "                request = self.getline('help> ')\n", '                if not request: break\n', '            except (KeyboardInterrupt, EOFError):\n', '                break\n', '            request = request.strip()\n', '\n', "            # Make sure significant trailing quoting marks of literals don't\n", '            # get deleted while cleaning input\n', '            if (len(request) > 2 and request[0] == request[-1] in ("\'", \'"\')\n', '                    and request[0] not in request[1:-1]):\n', '                request = request[1:-1]\n', "            if request.lower() in ('q', 'quit'): break\n", "            if request == 'help':\n", '                self.intro()\n', '            else:\n', '                self.help(request)\n', '\n', '    def getline(self, prompt):\n', '        """Read one line, using input() when appropriate."""\n', '        if self.input is sys.stdin:\n', '            return input(prompt)\n', '        else:\n', '            self.output.write(prompt)\n', '            self.output.flush()\n', '            return self.input.readline()\n', '\n', '    def help(self, request):\n', "        if type(request) is type(''):\n", '            request = request.strip()\n', "            if request == 'keywords': self.listkeywords()\n", "            elif request == 'symbols': self.listsymbols()\n", "            elif request == 'topics': self.listtopics()\n", "            elif request == 'modules': self.listmodules()\n", "            elif request[:8] == 'modules ':\n", '                self.listmodules(request.split()[1])\n', '            elif request in self.symbols: self.showsymbol(request)\n', "            elif request in ['True', 'False', 'None']:\n", '                # special case these keywords since they are objects too\n', "                doc(eval(request), 'Help on %s:')\n", '            elif request in self.keywords: self.showtopic(request)\n', '            elif request in self.topics: self.showtopic(request)\n', "            elif request: doc(request, 'Help on %s:', output=self._output)\n", "            else: doc(str, 'Help on %s:', output=self._output)\n", '        elif isinstance(request, Helper): self()\n', "        else: doc(request, 'Help on %s:', output=self._output)\n", "        self.output.write('\\n')\n", '\n', '    def intro(self):\n', "        self.output.write('''\n", "Welcome to Python {0}'s help utility!\n", '\n', 'If this is your first time using Python, you should definitely check out\n', 'the tutorial on the internet at https://docs.python.org/{0}/tutorial/.\n', '\n', 'Enter the name of any module, keyword, or topic to get help on writing\n', 'Python programs and using Python modules.  To quit this help utility and\n', 'return to the interpreter, just type "quit".\n', '\n', 'To get a list of available modules, keywords, symbols, or topics, type\n', '"modules", "keywords", "symbols", or "topics".  Each module also comes\n', 'with a one-line summary of what it does; to list the modules whose name\n', 'or summary contain a given string such as "spam", type "modules spam".\n', "'''.format('%d.%d' % sys.version_info[:2]))\n", '\n', '    def list(self, items, columns=4, width=80):\n', '        items = list(sorted(items))\n', '        colw = width // columns\n', '        rows = (len(items) + columns - 1) // columns\n', '        for row in range(rows):\n', '            for col in range(columns):\n', '                i = col * rows + row\n', '                if i < len(items):\n', '                    self.output.write(items[i])\n', '                    if col < columns - 1:\n', "                        self.output.write(' ' + ' ' * (colw - 1 - len(items[i])))\n", "            self.output.write('\\n')\n", '\n', '    def listkeywords(self):\n', "        self.output.write('''\n", 'Here is a list of the Python keywords.  Enter any keyword to get more help.\n', '\n', "''')\n", '        self.list(self.keywords.keys())\n', '\n', '    def listsymbols(self):\n', "        self.output.write('''\n", 'Here is a list of the punctuation symbols which Python assigns special meaning\n', 'to. Enter any symbol to get more help.\n', '\n', "''')\n", '        self.list(self.symbols.keys())\n', '\n', '    def listtopics(self):\n', "        self.output.write('''\n", 'Here is a list of available topics.  Enter any topic name to get more help.\n', '\n', "''')\n", '        self.list(self.topics.keys())\n', '\n', "    def showtopic(self, topic, more_xrefs=''):\n", '        try:\n', '            import pydoc_data.topics\n', '        except ImportError:\n', "            self.output.write('''\n", 'Sorry, topic and keyword documentation is not available because the\n', 'module "pydoc_data.topics" could not be found.\n', "''')\n", '            return\n', '        target = self.topics.get(topic, self.keywords.get(topic))\n', '        if not target:\n', "            self.output.write('no documentation found for %s\\n' % repr(topic))\n", '            return\n', "        if type(target) is type(''):\n", '            return self.showtopic(target, more_xrefs)\n', '\n', '        label, xrefs = target\n', '        try:\n', '            doc = pydoc_data.topics.topics[label]\n', '        except KeyError:\n', "            self.output.write('no documentation found for %s\\n' % repr(topic))\n", '            return\n', "        doc = doc.strip() + '\\n'\n", '        if more_xrefs:\n', "            xrefs = (xrefs or '') + ' ' + more_xrefs\n", '        if xrefs:\n', '            import textwrap\n', "            text = 'Related help topics: ' + ', '.join(xrefs.split()) + '\\n'\n", '            wrapped_text = textwrap.wrap(text, 72)\n', "            doc += '\\n%s\\n' % '\\n'.join(wrapped_text)\n", '        pager(doc)\n', '\n', "    def _gettopic(self, topic, more_xrefs=''):\n", '        """Return unbuffered tuple of (topic, xrefs).\n', '\n', '        If an error occurs here, the exception is caught and displayed by\n', '        the url handler.\n', '\n', '        This function duplicates the showtopic method but returns its\n', '        result directly so it can be formatted for display in an html page.\n', '        """\n', '        try:\n', '            import pydoc_data.topics\n', '        except ImportError:\n', "            return('''\n", 'Sorry, topic and keyword documentation is not available because the\n', 'module "pydoc_data.topics" could not be found.\n', "''' , '')\n", '        target = self.topics.get(topic, self.keywords.get(topic))\n', '        if not target:\n', "            raise ValueError('could not find topic')\n", '        if isinstance(target, str):\n', '            return self._gettopic(target, more_xrefs)\n', '        label, xrefs = target\n', '        doc = pydoc_data.topics.topics[label]\n', '        if more_xrefs:\n', "            xrefs = (xrefs or '') + ' ' + more_xrefs\n", '        return doc, xrefs\n', '\n', '    def showsymbol(self, symbol):\n', '        target = self.symbols[symbol]\n', "        topic, _, xrefs = target.partition(' ')\n", '        self.showtopic(topic, xrefs)\n', '\n', "    def listmodules(self, key=''):\n", '        if key:\n', "            self.output.write('''\n", "Here is a list of modules whose name or summary contains '{}'.\n", 'If there are any, enter a module name to get more help.\n', '\n', "'''.format(key))\n", '            apropos(key)\n', '        else:\n', "            self.output.write('''\n", 'Please wait a moment while I gather a list of all available modules...\n', '\n', "''')\n", '            modules = {}\n', '            def callback(path, modname, desc, modules=modules):\n', "                if modname and modname[-9:] == '.__init__':\n", "                    modname = modname[:-9] + ' (package)'\n", "                if modname.find('.') < 0:\n", '                    modules[modname] = 1\n', '            def onerror(modname):\n', '                callback(None, modname, None)\n', '            ModuleScanner().run(callback, onerror=onerror)\n', '            self.list(modules.keys())\n', "            self.output.write('''\n", 'Enter any module name to get more help.  Or, type "modules spam" to search\n', 'for modules whose name or summary contain the string "spam".\n', "''')\n", '\n', 'help = Helper()\n', '\n', 'class ModuleScanner:\n', '    """An interruptible scanner that searches module synopses."""\n', '\n', '    def run(self, callback, key=None, completer=None, onerror=None):\n', '        if key: key = key.lower()\n', '        self.quit = False\n', '        seen = {}\n', '\n', '        for modname in sys.builtin_module_names:\n', "            if modname != '__main__':\n", '                seen[modname] = 1\n', '                if key is None:\n', "                    callback(None, modname, '')\n", '                else:\n', "                    name = __import__(modname).__doc__ or ''\n", "                    desc = name.split('\\n')[0]\n", "                    name = modname + ' - ' + desc\n", '                    if name.lower().find(key) >= 0:\n', '                        callback(None, modname, desc)\n', '\n', '        for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror):\n', '            if self.quit:\n', '                break\n', '\n', '            if key is None:\n', "                callback(None, modname, '')\n", '            else:\n', '                try:\n', '                    spec = pkgutil._get_spec(importer, modname)\n', '                except SyntaxError:\n', '                    # raised by tests for bad coding cookies or BOM\n', '                    continue\n', '                loader = spec.loader\n', "                if hasattr(loader, 'get_source'):\n", '                    try:\n', '                        source = loader.get_source(modname)\n', '                    except Exception:\n', '                        if onerror:\n', '                            onerror(modname)\n', '                        continue\n', "                    desc = source_synopsis(io.StringIO(source)) or ''\n", "                    if hasattr(loader, 'get_filename'):\n", '                        path = loader.get_filename(modname)\n', '                    else:\n', '                        path = None\n', '                else:\n', '                    try:\n', '                        module = importlib._bootstrap._load(spec)\n', '                    except ImportError:\n', '                        if onerror:\n', '                            onerror(modname)\n', '                        continue\n', "                    desc = module.__doc__.splitlines()[0] if module.__doc__ else ''\n", "                    path = getattr(module,'__file__',None)\n", "                name = modname + ' - ' + desc\n", '                if name.lower().find(key) >= 0:\n', '                    callback(path, modname, desc)\n', '\n', '        if completer:\n', '            completer()\n', '\n', 'def apropos(key):\n', '    """Print all the one-line module summaries that contain a substring."""\n', '    def callback(path, modname, desc):\n', "        if modname[-9:] == '.__init__':\n", "            modname = modname[:-9] + ' (package)'\n", "        print(modname, desc and '- ' + desc)\n", '    def onerror(modname):\n', '        pass\n', '    with warnings.catch_warnings():\n', "        warnings.filterwarnings('ignore') # ignore problems during import\n", '        ModuleScanner().run(callback, key, onerror=onerror)\n', '\n', '# --------------------------------------- enhanced web browser interface\n', '\n', 'def _start_server(urlhandler, hostname, port):\n', '    """Start an HTTP server thread on a specific port.\n', '\n', '    Start an HTML/text server thread, so HTML or text documents can be\n', '    browsed dynamically and interactively with a web browser.  Example use:\n', '\n', '        >>> import time\n', '        >>> import pydoc\n', '\n', '        Define a URL handler.  To determine what the client is asking\n', '        for, check the URL and content_type.\n', '\n', '        Then get or generate some text or HTML code and return it.\n', '\n', '        >>> def my_url_handler(url, content_type):\n', "        ...     text = 'the URL sent was: (%s, %s)' % (url, content_type)\n", '        ...     return text\n', '\n', '        Start server thread on port 0.\n', '        If you use port 0, the server will pick a random port number.\n', '        You can then use serverthread.port to get the port number.\n', '\n', '        >>> port = 0\n', '        >>> serverthread = pydoc._start_server(my_url_handler, port)\n', '\n', '        Check that the server is really started.  If it is, open browser\n', '        and get first page.  Use serverthread.url as the starting page.\n', '\n', '        >>> if serverthread.serving:\n', '        ...    import webbrowser\n', '\n', "        The next two lines are commented out so a browser doesn't open if\n", '        doctest is run on this module.\n', '\n', '        #...    webbrowser.open(serverthread.url)\n', '        #True\n', '\n', '        Let the server do its thing. We just need to monitor its status.\n', "        Use time.sleep so the loop doesn't hog the CPU.\n", '\n', '        >>> starttime = time.monotonic()\n', '        >>> timeout = 1                    #seconds\n', '\n', '        This is a short timeout for testing purposes.\n', '\n', '        >>> while serverthread.serving:\n', '        ...     time.sleep(.01)\n', '        ...     if serverthread.serving and time.monotonic() - starttime > timeout:\n', '        ...          serverthread.stop()\n', '        ...          break\n', '\n', '        Print any errors that may have occurred.\n', '\n', '        >>> print(serverthread.error)\n', '        None\n', '   """\n', '    import http.server\n', '    import email.message\n', '    import select\n', '    import threading\n', '\n', '    class DocHandler(http.server.BaseHTTPRequestHandler):\n', '\n', '        def do_GET(self):\n', '            """Process a request from an HTML browser.\n', '\n', '            The URL received is in self.path.\n', '            Get an HTML page from self.urlhandler and send it.\n', '            """\n', "            if self.path.endswith('.css'):\n", "                content_type = 'text/css'\n", '            else:\n', "                content_type = 'text/html'\n", '            self.send_response(200)\n', "            self.send_header('Content-Type', '%s; charset=UTF-8' % content_type)\n", '            self.end_headers()\n', '            self.wfile.write(self.urlhandler(\n', "                self.path, content_type).encode('utf-8'))\n", '\n', '        def log_message(self, *args):\n', "            # Don't log messages.\n", '            pass\n', '\n', '    class DocServer(http.server.HTTPServer):\n', '\n', '        def __init__(self, host, port, callback):\n', '            self.host = host\n', '            self.address = (self.host, port)\n', '            self.callback = callback\n', '            self.base.__init__(self, self.address, self.handler)\n', '            self.quit = False\n', '\n', '        def serve_until_quit(self):\n', '            while not self.quit:\n', '                rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)\n', '                if rd:\n', '                    self.handle_request()\n', '            self.server_close()\n', '\n', '        def server_activate(self):\n', '            self.base.server_activate(self)\n', '            if self.callback:\n', '                self.callback(self)\n', '\n', '    class ServerThread(threading.Thread):\n', '\n', '        def __init__(self, urlhandler, host, port):\n', '            self.urlhandler = urlhandler\n', '            self.host = host\n', '            self.port = int(port)\n', '            threading.Thread.__init__(self)\n', '            self.serving = False\n', '            self.error = None\n', '\n', '        def run(self):\n', '            """Start the server."""\n', '            try:\n', '                DocServer.base = http.server.HTTPServer\n', '                DocServer.handler = DocHandler\n', '                DocHandler.MessageClass = email.message.Message\n', '                DocHandler.urlhandler = staticmethod(self.urlhandler)\n', '                docsvr = DocServer(self.host, self.port, self.ready)\n', '                self.docserver = docsvr\n', '                docsvr.serve_until_quit()\n', '            except Exception as e:\n', '                self.error = e\n', '\n', '        def ready(self, server):\n', '            self.serving = True\n', '            self.host = server.host\n', '            self.port = server.server_port\n', "            self.url = 'http://%s:%d/' % (self.host, self.port)\n", '\n', '        def stop(self):\n', '            """Stop the server and this thread nicely"""\n', '            self.docserver.quit = True\n', '            self.join()\n', '            # explicitly break a reference cycle: DocServer.callback\n', '            # has indirectly a reference to ServerThread.\n', '            self.docserver = None\n', '            self.serving = False\n', '            self.url = None\n', '\n', '    thread = ServerThread(urlhandler, hostname, port)\n', '    thread.start()\n', '    # Wait until thread.serving is True to make sure we are\n', '    # really up before returning.\n', '    while not thread.error and not thread.serving:\n', '        time.sleep(.01)\n', '    return thread\n', '\n', '\n', 'def _url_handler(url, content_type="text/html"):\n', '    """The pydoc url handler for use with the pydoc server.\n', '\n', "    If the content_type is 'text/css', the _pydoc.css style\n", '    sheet is read and returned if it exits.\n', '\n', "    If the content_type is 'text/html', then the result of\n", '    get_html_page(url) is returned.\n', '    """\n', '    class _HTMLDoc(HTMLDoc):\n', '\n', '        def page(self, title, contents):\n', '            """Format an HTML page."""\n', '            css_path = "pydoc_data/_pydoc.css"\n', '            css_link = (\n', '                \'<link rel="stylesheet" type="text/css" href="%s">\' %\n', '                css_path)\n', "            return '''\\\n", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\n', '<html><head><title>Pydoc: %s</title>\n', '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n', '%s</head><body bgcolor="#f0f0f8">%s<div style="clear:both;padding-top:.5em;">%s</div>\n', "</body></html>''' % (title, css_link, html_navbar(), contents)\n", '\n', '\n', '    html = _HTMLDoc()\n', '\n', '    def html_navbar():\n', '        version = html.escape("%s [%s, %s]" % (platform.python_version(),\n', '                                               platform.python_build()[0],\n', '                                               platform.python_compiler()))\n', '        return """\n', "            <div style='float:left'>\n", '                Python %s<br>%s\n', '            </div>\n', "            <div style='float:right'>\n", "                <div style='text-align:center'>\n", '                  <a href="index.html">Module Index</a>\n', '                  : <a href="topics.html">Topics</a>\n', '                  : <a href="keywords.html">Keywords</a>\n', '                </div>\n', '                <div>\n', '                    <form action="get" style=\'display:inline;\'>\n', '                      <input type=text name=key size=15>\n', '                      <input type=submit value="Get">\n', '                    </form>&nbsp;\n', '                    <form action="search" style=\'display:inline;\'>\n', '                      <input type=text name=key size=15>\n', '                      <input type=submit value="Search">\n', '                    </form>\n', '                </div>\n', '            </div>\n', '            """ % (version, html.escape(platform.platform(terse=True)))\n', '\n', '    def html_index():\n', '        """Module Index page."""\n', '\n', '        def bltinlink(name):\n', '            return \'<a href="%s.html">%s</a>\' % (name, name)\n', '\n', '        heading = html.heading(\n', "            '<big><big><strong>Index of Modules</strong></big></big>',\n", "            '#ffffff', '#7799ee')\n", '        names = [name for name in sys.builtin_module_names\n', "                 if name != '__main__']\n", '        contents = html.multicolumn(names, bltinlink)\n', "        contents = [heading, '<p>' + html.bigsection(\n", "            'Built-in Modules', '#ffffff', '#ee77aa', contents)]\n", '\n', '        seen = {}\n', '        for dir in sys.path:\n', '            contents.append(html.index(dir, seen))\n', '\n', '        contents.append(\n', '            \'<p align=right><font color="#909090" face="helvetica,\'\n', '            \'arial"><strong>pydoc</strong> by Ka-Ping Yee\'\n', "            '&lt;ping@lfw.org&gt;</font>')\n", "        return 'Index of Modules', ''.join(contents)\n", '\n', '    def html_search(key):\n', '        """Search results page."""\n', '        # scan for modules\n', '        search_result = []\n', '\n', '        def callback(path, modname, desc):\n', "            if modname[-9:] == '.__init__':\n", "                modname = modname[:-9] + ' (package)'\n", "            search_result.append((modname, desc and '- ' + desc))\n", '\n', '        with warnings.catch_warnings():\n', "            warnings.filterwarnings('ignore') # ignore problems during import\n", '            def onerror(modname):\n', '                pass\n', '            ModuleScanner().run(callback, key, onerror=onerror)\n', '\n', '        # format page\n', '        def bltinlink(name):\n', '            return \'<a href="%s.html">%s</a>\' % (name, name)\n', '\n', '        results = []\n', '        heading = html.heading(\n', "            '<big><big><strong>Search Results</strong></big></big>',\n", "            '#ffffff', '#7799ee')\n", '        for name, desc in search_result:\n', '            results.append(bltinlink(name) + desc)\n', '        contents = heading + html.bigsection(\n', "            'key = %s' % key, '#ffffff', '#ee77aa', '<br>'.join(results))\n", "        return 'Search Results', contents\n", '\n', '    def html_topics():\n', '        """Index of topic texts available."""\n', '\n', '        def bltinlink(name):\n', '            return \'<a href="topic?key=%s">%s</a>\' % (name, name)\n', '\n', '        heading = html.heading(\n', "            '<big><big><strong>INDEX</strong></big></big>',\n", "            '#ffffff', '#7799ee')\n", '        names = sorted(Helper.topics.keys())\n', '\n', '        contents = html.multicolumn(names, bltinlink)\n', '        contents = heading + html.bigsection(\n', "            'Topics', '#ffffff', '#ee77aa', contents)\n", "        return 'Topics', contents\n", '\n', '    def html_keywords():\n', '        """Index of keywords."""\n', '        heading = html.heading(\n', "            '<big><big><strong>INDEX</strong></big></big>',\n", "            '#ffffff', '#7799ee')\n", '        names = sorted(Helper.keywords.keys())\n', '\n', '        def bltinlink(name):\n', '            return \'<a href="topic?key=%s">%s</a>\' % (name, name)\n', '\n', '        contents = html.multicolumn(names, bltinlink)\n', '        contents = heading + html.bigsection(\n', "            'Keywords', '#ffffff', '#ee77aa', contents)\n", "        return 'Keywords', contents\n", '\n', '    def html_topicpage(topic):\n', '        """Topic or keyword help page."""\n', '        buf = io.StringIO()\n', '        htmlhelp = Helper(buf, buf)\n', '        contents, xrefs = htmlhelp._gettopic(topic)\n', '        if topic in htmlhelp.keywords:\n', "            title = 'KEYWORD'\n", '        else:\n', "            title = 'TOPIC'\n", '        heading = html.heading(\n', "            '<big><big><strong>%s</strong></big></big>' % title,\n", "            '#ffffff', '#7799ee')\n", "        contents = '<pre>%s</pre>' % html.markup(contents)\n", "        contents = html.bigsection(topic , '#ffffff','#ee77aa', contents)\n", '        if xrefs:\n', '            xrefs = sorted(xrefs.split())\n', '\n', '            def bltinlink(name):\n', '                return \'<a href="topic?key=%s">%s</a>\' % (name, name)\n', '\n', '            xrefs = html.multicolumn(xrefs, bltinlink)\n', "            xrefs = html.section('Related help topics: ',\n", "                                 '#ffffff', '#ee77aa', xrefs)\n", "        return ('%s %s' % (title, topic),\n", "                ''.join((heading, contents, xrefs)))\n", '\n', '    def html_getobj(url):\n', '        obj = locate(url, forceload=1)\n', "        if obj is None and url != 'None':\n", "            raise ValueError('could not find object')\n", '        title = describe(obj)\n', '        content = html.document(obj, url)\n', '        return title, content\n', '\n', '    def html_error(url, exc):\n', '        heading = html.heading(\n', "            '<big><big><strong>Error</strong></big></big>',\n", "            '#ffffff', '#7799ee')\n", "        contents = '<br>'.join(html.escape(line) for line in\n", '                               format_exception_only(type(exc), exc))\n', "        contents = heading + html.bigsection(url, '#ffffff', '#bb0000',\n", '                                             contents)\n', '        return "Error - %s" % url, contents\n', '\n', '    def get_html_page(url):\n', '        """Generate an HTML page for url."""\n', '        complete_url = url\n', "        if url.endswith('.html'):\n", '            url = url[:-5]\n', '        try:\n', '            if url in ("", "index"):\n', '                title, content = html_index()\n', '            elif url == "topics":\n', '                title, content = html_topics()\n', '            elif url == "keywords":\n', '                title, content = html_keywords()\n', "            elif '=' in url:\n", "                op, _, url = url.partition('=')\n", '                if op == "search?key":\n', '                    title, content = html_search(url)\n', '                elif op == "topic?key":\n', '                    # try topics first, then objects.\n', '                    try:\n', '                        title, content = html_topicpage(url)\n', '                    except ValueError:\n', '                        title, content = html_getobj(url)\n', '                elif op == "get?key":\n', '                    # try objects first, then topics.\n', '                    if url in ("", "index"):\n', '                        title, content = html_index()\n', '                    else:\n', '                        try:\n', '                            title, content = html_getobj(url)\n', '                        except ValueError:\n', '                            title, content = html_topicpage(url)\n', '                else:\n', "                    raise ValueError('bad pydoc url')\n", '            else:\n', '                title, content = html_getobj(url)\n', '        except Exception as exc:\n', '            # Catch any errors and display them in an error page.\n', '            title, content = html_error(complete_url, exc)\n', '        return html.page(title, content)\n', '\n', "    if url.startswith('/'):\n", '        url = url[1:]\n', "    if content_type == 'text/css':\n", '        path_here = os.path.dirname(os.path.realpath(__file__))\n', '        css_path = os.path.join(path_here, url)\n', '        with open(css_path) as fp:\n', "            return ''.join(fp.readlines())\n", "    elif content_type == 'text/html':\n", '        return get_html_page(url)\n', '    # Errors outside the url handler are caught by the server.\n', "    raise TypeError('unknown content type %r for url %s' % (content_type, url))\n", '\n', '\n', "def browse(port=0, *, open_browser=True, hostname='localhost'):\n", '    """Start the enhanced pydoc web server and open a web browser.\n', '\n', "    Use port '0' to start the server on an arbitrary port.\n", '    Set open_browser to False to suppress opening a browser.\n', '    """\n', '    import webbrowser\n', '    serverthread = _start_server(_url_handler, hostname, port)\n', '    if serverthread.error:\n', '        print(serverthread.error)\n', '        return\n', '    if serverthread.serving:\n', "        server_help_msg = 'Server commands: [b]rowser, [q]uit'\n", '        if open_browser:\n', '            webbrowser.open(serverthread.url)\n', '        try:\n', "            print('Server ready at', serverthread.url)\n", '            print(server_help_msg)\n', '            while serverthread.serving:\n', "                cmd = input('server> ')\n", '                cmd = cmd.lower()\n', "                if cmd == 'q':\n", '                    break\n', "                elif cmd == 'b':\n", '                    webbrowser.open(serverthread.url)\n', '                else:\n', '                    print(server_help_msg)\n', '        except (KeyboardInterrupt, EOFError):\n', '            print()\n', '        finally:\n', '            if serverthread.serving:\n', '                serverthread.stop()\n', "                print('Server stopped')\n", '\n', '\n', '# -------------------------------------------------- command-line interface\n', '\n', 'def ispath(x):\n', '    return isinstance(x, str) and x.find(os.sep) >= 0\n', '\n', 'def _get_revised_path(given_path, argv0):\n', '    """Ensures current directory is on returned path, and argv0 directory is not\n', '\n', "    Exception: argv0 dir is left alone if it's also pydoc's directory.\n", '\n', '    Returns a new path entry list, or None if no adjustment is needed.\n', '    """\n', "    # Scripts may get the current directory in their path by default if they're\n", '    # run with the -m switch, or directly from the current directory.\n', '    # The interactive prompt also allows imports from the current directory.\n', '\n', "    # Accordingly, if the current directory is already present, don't make\n", '    # any changes to the given_path\n', "    if '' in given_path or os.curdir in given_path or os.getcwd() in given_path:\n", '        return None\n', '\n', '    # Otherwise, add the current directory to the given path, and remove the\n', "    # script directory (as long as the latter isn't also pydoc's directory.\n", '    stdlib_dir = os.path.dirname(__file__)\n', '    script_dir = os.path.dirname(argv0)\n', '    revised_path = given_path.copy()\n', '    if script_dir in given_path and not os.path.samefile(script_dir, stdlib_dir):\n', '        revised_path.remove(script_dir)\n', '    revised_path.insert(0, os.getcwd())\n', '    return revised_path\n', '\n', '\n', '# Note: the tests only cover _get_revised_path, not _adjust_cli_path itself\n', 'def _adjust_cli_sys_path():\n', '    """Ensures current directory is on sys.path, and __main__ directory is not.\n', '\n', "    Exception: __main__ dir is left alone if it's also pydoc's directory.\n", '    """\n', '    revised_path = _get_revised_path(sys.path, sys.argv[0])\n', '    if revised_path is not None:\n', '        sys.path[:] = revised_path\n', '\n', '\n', 'def cli():\n', '    """Command-line interface (looks at sys.argv to decide what to do)."""\n', '    import getopt\n', '    class BadUsage(Exception): pass\n', '\n', '    _adjust_cli_sys_path()\n', '\n', '    try:\n', "        opts, args = getopt.getopt(sys.argv[1:], 'bk:n:p:w')\n", '        writing = False\n', '        start_server = False\n', '        open_browser = False\n', '        port = 0\n', "        hostname = 'localhost'\n", '        for opt, val in opts:\n', "            if opt == '-b':\n", '                start_server = True\n', '                open_browser = True\n', "            if opt == '-k':\n", '                apropos(val)\n', '                return\n', "            if opt == '-p':\n", '                start_server = True\n', '                port = val\n', "            if opt == '-w':\n", '                writing = True\n', "            if opt == '-n':\n", '                start_server = True\n', '                hostname = val\n', '\n', '        if start_server:\n', '            browse(port, hostname=hostname, open_browser=open_browser)\n', '            return\n', '\n', '        if not args: raise BadUsage\n', '        for arg in args:\n', '            if ispath(arg) and not os.path.exists(arg):\n', "                print('file %r does not exist' % arg)\n", '                break\n', '            try:\n', '                if ispath(arg) and os.path.isfile(arg):\n', '                    arg = importfile(arg)\n', '                if writing:\n', '                    if ispath(arg) and os.path.isdir(arg):\n', '                        writedocs(arg)\n', '                    else:\n', '                        writedoc(arg)\n', '                else:\n', '                    help.help(arg)\n', '            except ErrorDuringImport as value:\n', '                print(value)\n', '\n', '    except (getopt.error, BadUsage):\n', '        cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0]\n', '        print("""pydoc - the Python documentation tool\n', '\n', '{cmd} <name> ...\n', '    Show text documentation on something.  <name> may be the name of a\n', '    Python keyword, topic, function, module, or package, or a dotted\n', '    reference to a class or function within a module or module in a\n', "    package.  If <name> contains a '{sep}', it is used as the path to a\n", "    Python source file to document. If name is 'keywords', 'topics',\n", "    or 'modules', a listing of these things is displayed.\n", '\n', '{cmd} -k <keyword>\n', '    Search for a keyword in the synopsis lines of all available modules.\n', '\n', '{cmd} -n <hostname>\n', '    Start an HTTP server with the given hostname (default: localhost).\n', '\n', '{cmd} -p <port>\n', '    Start an HTTP server on the given port on the local machine.  Port\n', '    number 0 can be used to get an arbitrary unused port.\n', '\n', '{cmd} -b\n', '    Start an HTTP server on an arbitrary unused port and open a web browser\n', '    to interactively browse documentation.  This option can be used in\n', '    combination with -n and/or -p.\n', '\n', '{cmd} -w <name> ...\n', '    Write out the HTML documentation for a module to a file in the current\n', "    directory.  If <name> contains a '{sep}', it is treated as a filename; if\n", '    it names a directory, documentation is written for all the contents.\n', '""".format(cmd=cmd, sep=os.sep))\n', '\n', "if __name__ == '__main__':\n", '    cli()\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/pydoc.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/events.py': (27224, 1.0, ['"""Event loop and event loop policy."""\n', '\n', '__all__ = (\n', "    'AbstractEventLoopPolicy',\n", "    'AbstractEventLoop', 'AbstractServer',\n", "    'Handle', 'TimerHandle',\n", "    'get_event_loop_policy', 'set_event_loop_policy',\n", "    'get_event_loop', 'set_event_loop', 'new_event_loop',\n", "    'get_child_watcher', 'set_child_watcher',\n", "    '_set_running_loop', 'get_running_loop',\n", "    '_get_running_loop',\n", ')\n', '\n', 'import contextvars\n', 'import os\n', 'import socket\n', 'import subprocess\n', 'import sys\n', 'import threading\n', '\n', 'from . import format_helpers\n', '\n', '\n', 'class Handle:\n', '    """Object returned by callback registration methods."""\n', '\n', "    __slots__ = ('_callback', '_args', '_cancelled', '_loop',\n", "                 '_source_traceback', '_repr', '__weakref__',\n", "                 '_context')\n", '\n', '    def __init__(self, callback, args, loop, context=None):\n', '        if context is None:\n', '            context = contextvars.copy_context()\n', '        self._context = context\n', '        self._loop = loop\n', '        self._callback = callback\n', '        self._args = args\n', '        self._cancelled = False\n', '        self._repr = None\n', '        if self._loop.get_debug():\n', '            self._source_traceback = format_helpers.extract_stack(\n', '                sys._getframe(1))\n', '        else:\n', '            self._source_traceback = None\n', '\n', '    def _repr_info(self):\n', '        info = [self.__class__.__name__]\n', '        if self._cancelled:\n', "            info.append('cancelled')\n", '        if self._callback is not None:\n', '            info.append(format_helpers._format_callback_source(\n', '                self._callback, self._args))\n', '        if self._source_traceback:\n', '            frame = self._source_traceback[-1]\n', "            info.append(f'created at {frame[0]}:{frame[1]}')\n", '        return info\n', '\n', '    def __repr__(self):\n', '        if self._repr is not None:\n', '            return self._repr\n', '        info = self._repr_info()\n', "        return '<{}>'.format(' '.join(info))\n", '\n', '    def cancel(self):\n', '        if not self._cancelled:\n', '            self._cancelled = True\n', '            if self._loop.get_debug():\n', '                # Keep a representation in debug mode to keep callback and\n', '                # parameters. For example, to log the warning\n', '                # "Executing <Handle...> took 2.5 second"\n', '                self._repr = repr(self)\n', '            self._callback = None\n', '            self._args = None\n', '\n', '    def cancelled(self):\n', '        return self._cancelled\n', '\n', '    def _run(self):\n', '        try:\n', '            self._context.run(self._callback, *self._args)\n', '        except (SystemExit, KeyboardInterrupt):\n', '            raise\n', '        except BaseException as exc:\n', '            cb = format_helpers._format_callback_source(\n', '                self._callback, self._args)\n', "            msg = f'Exception in callback {cb}'\n", '            context = {\n', "                'message': msg,\n", "                'exception': exc,\n", "                'handle': self,\n", '            }\n', '            if self._source_traceback:\n', "                context['source_traceback'] = self._source_traceback\n", '            self._loop.call_exception_handler(context)\n', '        self = None  # Needed to break cycles when an exception occurs.\n', '\n', '\n', 'class TimerHandle(Handle):\n', '    """Object returned by timed callback registration methods."""\n', '\n', "    __slots__ = ['_scheduled', '_when']\n", '\n', '    def __init__(self, when, callback, args, loop, context=None):\n', '        assert when is not None\n', '        super().__init__(callback, args, loop, context)\n', '        if self._source_traceback:\n', '            del self._source_traceback[-1]\n', '        self._when = when\n', '        self._scheduled = False\n', '\n', '    def _repr_info(self):\n', '        info = super()._repr_info()\n', '        pos = 2 if self._cancelled else 1\n', "        info.insert(pos, f'when={self._when}')\n", '        return info\n', '\n', '    def __hash__(self):\n', '        return hash(self._when)\n', '\n', '    def __lt__(self, other):\n', '        if isinstance(other, TimerHandle):\n', '            return self._when < other._when\n', '        return NotImplemented\n', '\n', '    def __le__(self, other):\n', '        if isinstance(other, TimerHandle):\n', '            return self._when < other._when or self.__eq__(other)\n', '        return NotImplemented\n', '\n', '    def __gt__(self, other):\n', '        if isinstance(other, TimerHandle):\n', '            return self._when > other._when\n', '        return NotImplemented\n', '\n', '    def __ge__(self, other):\n', '        if isinstance(other, TimerHandle):\n', '            return self._when > other._when or self.__eq__(other)\n', '        return NotImplemented\n', '\n', '    def __eq__(self, other):\n', '        if isinstance(other, TimerHandle):\n', '            return (self._when == other._when and\n', '                    self._callback == other._callback and\n', '                    self._args == other._args and\n', '                    self._cancelled == other._cancelled)\n', '        return NotImplemented\n', '\n', '    def cancel(self):\n', '        if not self._cancelled:\n', '            self._loop._timer_handle_cancelled(self)\n', '        super().cancel()\n', '\n', '    def when(self):\n', '        """Return a scheduled callback time.\n', '\n', '        The time is an absolute timestamp, using the same time\n', '        reference as loop.time().\n', '        """\n', '        return self._when\n', '\n', '\n', 'class AbstractServer:\n', '    """Abstract server returned by create_server()."""\n', '\n', '    def close(self):\n', '        """Stop serving.  This leaves existing connections open."""\n', '        raise NotImplementedError\n', '\n', '    def get_loop(self):\n', '        """Get the event loop the Server object is attached to."""\n', '        raise NotImplementedError\n', '\n', '    def is_serving(self):\n', '        """Return True if the server is accepting connections."""\n', '        raise NotImplementedError\n', '\n', '    async def start_serving(self):\n', '        """Start accepting connections.\n', '\n', '        This method is idempotent, so it can be called when\n', '        the server is already being serving.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def serve_forever(self):\n', '        """Start accepting connections until the coroutine is cancelled.\n', '\n', '        The server is closed when the coroutine is cancelled.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def wait_closed(self):\n', '        """Coroutine to wait until service is closed."""\n', '        raise NotImplementedError\n', '\n', '    async def __aenter__(self):\n', '        return self\n', '\n', '    async def __aexit__(self, *exc):\n', '        self.close()\n', '        await self.wait_closed()\n', '\n', '\n', 'class AbstractEventLoop:\n', '    """Abstract event loop."""\n', '\n', '    # Running and stopping the event loop.\n', '\n', '    def run_forever(self):\n', '        """Run the event loop until stop() is called."""\n', '        raise NotImplementedError\n', '\n', '    def run_until_complete(self, future):\n', '        """Run the event loop until a Future is done.\n', '\n', "        Return the Future's result, or raise its exception.\n", '        """\n', '        raise NotImplementedError\n', '\n', '    def stop(self):\n', '        """Stop the event loop as soon as reasonable.\n', '\n', '        Exactly how soon that is may depend on the implementation, but\n', '        no more I/O callbacks should be scheduled.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    def is_running(self):\n', '        """Return whether the event loop is currently running."""\n', '        raise NotImplementedError\n', '\n', '    def is_closed(self):\n', '        """Returns True if the event loop was closed."""\n', '        raise NotImplementedError\n', '\n', '    def close(self):\n', '        """Close the loop.\n', '\n', '        The loop should not be running.\n', '\n', '        This is idempotent and irreversible.\n', '\n', '        No other methods should be called after this one.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def shutdown_asyncgens(self):\n', '        """Shutdown all active asynchronous generators."""\n', '        raise NotImplementedError\n', '\n', '    async def shutdown_default_executor(self):\n', '        """Schedule the shutdown of the default executor."""\n', '        raise NotImplementedError\n', '\n', '    # Methods scheduling callbacks.  All these return Handles.\n', '\n', '    def _timer_handle_cancelled(self, handle):\n', '        """Notification that a TimerHandle has been cancelled."""\n', '        raise NotImplementedError\n', '\n', '    def call_soon(self, callback, *args, context=None):\n', '        return self.call_later(0, callback, *args, context=context)\n', '\n', '    def call_later(self, delay, callback, *args, context=None):\n', '        raise NotImplementedError\n', '\n', '    def call_at(self, when, callback, *args, context=None):\n', '        raise NotImplementedError\n', '\n', '    def time(self):\n', '        raise NotImplementedError\n', '\n', '    def create_future(self):\n', '        raise NotImplementedError\n', '\n', '    # Method scheduling a coroutine object: create a task.\n', '\n', '    def create_task(self, coro, *, name=None):\n', '        raise NotImplementedError\n', '\n', '    # Methods for interacting with threads.\n', '\n', '    def call_soon_threadsafe(self, callback, *args, context=None):\n', '        raise NotImplementedError\n', '\n', '    def run_in_executor(self, executor, func, *args):\n', '        raise NotImplementedError\n', '\n', '    def set_default_executor(self, executor):\n', '        raise NotImplementedError\n', '\n', '    # Network I/O methods returning Futures.\n', '\n', '    async def getaddrinfo(self, host, port, *,\n', '                          family=0, type=0, proto=0, flags=0):\n', '        raise NotImplementedError\n', '\n', '    async def getnameinfo(self, sockaddr, flags=0):\n', '        raise NotImplementedError\n', '\n', '    async def create_connection(\n', '            self, protocol_factory, host=None, port=None,\n', '            *, ssl=None, family=0, proto=0,\n', '            flags=0, sock=None, local_addr=None,\n', '            server_hostname=None,\n', '            ssl_handshake_timeout=None,\n', '            happy_eyeballs_delay=None, interleave=None):\n', '        raise NotImplementedError\n', '\n', '    async def create_server(\n', '            self, protocol_factory, host=None, port=None,\n', '            *, family=socket.AF_UNSPEC,\n', '            flags=socket.AI_PASSIVE, sock=None, backlog=100,\n', '            ssl=None, reuse_address=None, reuse_port=None,\n', '            ssl_handshake_timeout=None,\n', '            start_serving=True):\n', '        """A coroutine which creates a TCP server bound to host and port.\n', '\n', '        The return value is a Server object which can be used to stop\n', '        the service.\n', '\n', '        If host is an empty string or None all interfaces are assumed\n', '        and a list of multiple sockets will be returned (most likely\n', '        one for IPv4 and another one for IPv6). The host parameter can also be\n', '        a sequence (e.g. list) of hosts to bind to.\n', '\n', '        family can be set to either AF_INET or AF_INET6 to force the\n', '        socket to use IPv4 or IPv6. If not set it will be determined\n', '        from host (defaults to AF_UNSPEC).\n', '\n', '        flags is a bitmask for getaddrinfo().\n', '\n', '        sock can optionally be specified in order to use a preexisting\n', '        socket object.\n', '\n', '        backlog is the maximum number of queued connections passed to\n', '        listen() (defaults to 100).\n', '\n', '        ssl can be set to an SSLContext to enable SSL over the\n', '        accepted connections.\n', '\n', '        reuse_address tells the kernel to reuse a local socket in\n', '        TIME_WAIT state, without waiting for its natural timeout to\n', '        expire. If not specified will automatically be set to True on\n', '        UNIX.\n', '\n', '        reuse_port tells the kernel to allow this endpoint to be bound to\n', '        the same port as other existing endpoints are bound to, so long as\n', '        they all set this flag when being created. This option is not\n', '        supported on Windows.\n', '\n', '        ssl_handshake_timeout is the time in seconds that an SSL server\n', '        will wait for completion of the SSL handshake before aborting the\n', '        connection. Default is 60s.\n', '\n', '        start_serving set to True (default) causes the created server\n', '        to start accepting connections immediately.  When set to False,\n', '        the user should await Server.start_serving() or Server.serve_forever()\n', '        to make the server to start accepting connections.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def sendfile(self, transport, file, offset=0, count=None,\n', '                       *, fallback=True):\n', '        """Send a file through a transport.\n', '\n', '        Return an amount of sent bytes.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def start_tls(self, transport, protocol, sslcontext, *,\n', '                        server_side=False,\n', '                        server_hostname=None,\n', '                        ssl_handshake_timeout=None):\n', '        """Upgrade a transport to TLS.\n', '\n', '        Return a new transport that *protocol* should start using\n', '        immediately.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def create_unix_connection(\n', '            self, protocol_factory, path=None, *,\n', '            ssl=None, sock=None,\n', '            server_hostname=None,\n', '            ssl_handshake_timeout=None):\n', '        raise NotImplementedError\n', '\n', '    async def create_unix_server(\n', '            self, protocol_factory, path=None, *,\n', '            sock=None, backlog=100, ssl=None,\n', '            ssl_handshake_timeout=None,\n', '            start_serving=True):\n', '        """A coroutine which creates a UNIX Domain Socket server.\n', '\n', '        The return value is a Server object, which can be used to stop\n', '        the service.\n', '\n', '        path is a str, representing a file system path to bind the\n', '        server socket to.\n', '\n', '        sock can optionally be specified in order to use a preexisting\n', '        socket object.\n', '\n', '        backlog is the maximum number of queued connections passed to\n', '        listen() (defaults to 100).\n', '\n', '        ssl can be set to an SSLContext to enable SSL over the\n', '        accepted connections.\n', '\n', '        ssl_handshake_timeout is the time in seconds that an SSL server\n', '        will wait for the SSL handshake to complete (defaults to 60s).\n', '\n', '        start_serving set to True (default) causes the created server\n', '        to start accepting connections immediately.  When set to False,\n', '        the user should await Server.start_serving() or Server.serve_forever()\n', '        to make the server to start accepting connections.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def connect_accepted_socket(\n', '            self, protocol_factory, sock,\n', '            *, ssl=None,\n', '            ssl_handshake_timeout=None):\n', '        """Handle an accepted connection.\n', '\n', '        This is used by servers that accept connections outside of\n', '        asyncio, but use asyncio to handle connections.\n', '\n', '        This method is a coroutine.  When completed, the coroutine\n', '        returns a (transport, protocol) pair.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    async def create_datagram_endpoint(self, protocol_factory,\n', '                                       local_addr=None, remote_addr=None, *,\n', '                                       family=0, proto=0, flags=0,\n', '                                       reuse_address=None, reuse_port=None,\n', '                                       allow_broadcast=None, sock=None):\n', '        """A coroutine which creates a datagram endpoint.\n', '\n', '        This method will try to establish the endpoint in the background.\n', '        When successful, the coroutine returns a (transport, protocol) pair.\n', '\n', '        protocol_factory must be a callable returning a protocol instance.\n', '\n', '        socket family AF_INET, socket.AF_INET6 or socket.AF_UNIX depending on\n', '        host (or family if specified), socket type SOCK_DGRAM.\n', '\n', '        reuse_address tells the kernel to reuse a local socket in\n', '        TIME_WAIT state, without waiting for its natural timeout to\n', '        expire. If not specified it will automatically be set to True on\n', '        UNIX.\n', '\n', '        reuse_port tells the kernel to allow this endpoint to be bound to\n', '        the same port as other existing endpoints are bound to, so long as\n', '        they all set this flag when being created. This option is not\n', "        supported on Windows and some UNIX's. If the\n", '        :py:data:`~socket.SO_REUSEPORT` constant is not defined then this\n', '        capability is unsupported.\n', '\n', '        allow_broadcast tells the kernel to allow this endpoint to send\n', '        messages to the broadcast address.\n', '\n', '        sock can optionally be specified in order to use a preexisting\n', '        socket object.\n', '        """\n', '        raise NotImplementedError\n', '\n', '    # Pipes and subprocesses.\n', '\n', '    async def connect_read_pipe(self, protocol_factory, pipe):\n', '        """Register read pipe in event loop. Set the pipe to non-blocking mode.\n', '\n', '        protocol_factory should instantiate object with Protocol interface.\n', '        pipe is a file-like object.\n', '        Return pair (transport, protocol), where transport supports the\n', '        ReadTransport interface."""\n', '        # The reason to accept file-like object instead of just file descriptor\n', '        # is: we need to own pipe and close it at transport finishing\n', '        # Can got complicated errors if pass f.fileno(),\n', '        # close fd in pipe transport then close f and vice versa.\n', '        raise NotImplementedError\n', '\n', '    async def connect_write_pipe(self, protocol_factory, pipe):\n', '        """Register write pipe in event loop.\n', '\n', '        protocol_factory should instantiate object with BaseProtocol interface.\n', '        Pipe is file-like object already switched to nonblocking.\n', '        Return pair (transport, protocol), where transport support\n', '        WriteTransport interface."""\n', '        # The reason to accept file-like object instead of just file descriptor\n', '        # is: we need to own pipe and close it at transport finishing\n', '        # Can got complicated errors if pass f.fileno(),\n', '        # close fd in pipe transport then close f and vice versa.\n', '        raise NotImplementedError\n', '\n', '    async def subprocess_shell(self, protocol_factory, cmd, *,\n', '                               stdin=subprocess.PIPE,\n', '                               stdout=subprocess.PIPE,\n', '                               stderr=subprocess.PIPE,\n', '                               **kwargs):\n', '        raise NotImplementedError\n', '\n', '    async def subprocess_exec(self, protocol_factory, *args,\n', '                              stdin=subprocess.PIPE,\n', '                              stdout=subprocess.PIPE,\n', '                              stderr=subprocess.PIPE,\n', '                              **kwargs):\n', '        raise NotImplementedError\n', '\n', '    # Ready-based callback registration methods.\n', '    # The add_*() methods return None.\n', '    # The remove_*() methods return True if something was removed,\n', '    # False if there was nothing to delete.\n', '\n', '    def add_reader(self, fd, callback, *args):\n', '        raise NotImplementedError\n', '\n', '    def remove_reader(self, fd):\n', '        raise NotImplementedError\n', '\n', '    def add_writer(self, fd, callback, *args):\n', '        raise NotImplementedError\n', '\n', '    def remove_writer(self, fd):\n', '        raise NotImplementedError\n', '\n', '    # Completion based I/O methods returning Futures.\n', '\n', '    async def sock_recv(self, sock, nbytes):\n', '        raise NotImplementedError\n', '\n', '    async def sock_recv_into(self, sock, buf):\n', '        raise NotImplementedError\n', '\n', '    async def sock_sendall(self, sock, data):\n', '        raise NotImplementedError\n', '\n', '    async def sock_connect(self, sock, address):\n', '        raise NotImplementedError\n', '\n', '    async def sock_accept(self, sock):\n', '        raise NotImplementedError\n', '\n', '    async def sock_sendfile(self, sock, file, offset=0, count=None,\n', '                            *, fallback=None):\n', '        raise NotImplementedError\n', '\n', '    # Signal handling.\n', '\n', '    def add_signal_handler(self, sig, callback, *args):\n', '        raise NotImplementedError\n', '\n', '    def remove_signal_handler(self, sig):\n', '        raise NotImplementedError\n', '\n', '    # Task factory.\n', '\n', '    def set_task_factory(self, factory):\n', '        raise NotImplementedError\n', '\n', '    def get_task_factory(self):\n', '        raise NotImplementedError\n', '\n', '    # Error handlers.\n', '\n', '    def get_exception_handler(self):\n', '        raise NotImplementedError\n', '\n', '    def set_exception_handler(self, handler):\n', '        raise NotImplementedError\n', '\n', '    def default_exception_handler(self, context):\n', '        raise NotImplementedError\n', '\n', '    def call_exception_handler(self, context):\n', '        raise NotImplementedError\n', '\n', '    # Debug flag management.\n', '\n', '    def get_debug(self):\n', '        raise NotImplementedError\n', '\n', '    def set_debug(self, enabled):\n', '        raise NotImplementedError\n', '\n', '\n', 'class AbstractEventLoopPolicy:\n', '    """Abstract policy for accessing the event loop."""\n', '\n', '    def get_event_loop(self):\n', '        """Get the event loop for the current context.\n', '\n', '        Returns an event loop object implementing the BaseEventLoop interface,\n', '        or raises an exception in case no event loop has been set for the\n', '        current context and the current policy does not specify to create one.\n', '\n', '        It should never return None."""\n', '        raise NotImplementedError\n', '\n', '    def set_event_loop(self, loop):\n', '        """Set the event loop for the current context to loop."""\n', '        raise NotImplementedError\n', '\n', '    def new_event_loop(self):\n', '        """Create and return a new event loop object according to this\n', "        policy's rules. If there's need to set this loop as the event loop for\n", '        the current context, set_event_loop must be called explicitly."""\n', '        raise NotImplementedError\n', '\n', '    # Child processes handling (Unix only).\n', '\n', '    def get_child_watcher(self):\n', '        "Get the watcher for child processes."\n', '        raise NotImplementedError\n', '\n', '    def set_child_watcher(self, watcher):\n', '        """Set the watcher for child processes."""\n', '        raise NotImplementedError\n', '\n', '\n', 'class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):\n', '    """Default policy implementation for accessing the event loop.\n', '\n', '    In this policy, each thread has its own event loop.  However, we\n', '    only automatically create an event loop by default for the main\n', '    thread; other threads by default have no event loop.\n', '\n', '    Other policies may have different rules (e.g. a single global\n', '    event loop, or automatically creating an event loop per thread, or\n', '    using some other notion of context to which an event loop is\n', '    associated).\n', '    """\n', '\n', '    _loop_factory = None\n', '\n', '    class _Local(threading.local):\n', '        _loop = None\n', '        _set_called = False\n', '\n', '    def __init__(self):\n', '        self._local = self._Local()\n', '\n', '    def get_event_loop(self):\n', '        """Get the event loop for the current context.\n', '\n', '        Returns an instance of EventLoop or raises an exception.\n', '        """\n', '        if (self._local._loop is None and\n', '                not self._local._set_called and\n', '                threading.current_thread() is threading.main_thread()):\n', '            self.set_event_loop(self.new_event_loop())\n', '\n', '        if self._local._loop is None:\n', "            raise RuntimeError('There is no current event loop in thread %r.'\n", '                               % threading.current_thread().name)\n', '\n', '        return self._local._loop\n', '\n', '    def set_event_loop(self, loop):\n', '        """Set the event loop."""\n', '        self._local._set_called = True\n', '        assert loop is None or isinstance(loop, AbstractEventLoop)\n', '        self._local._loop = loop\n', '\n', '    def new_event_loop(self):\n', '        """Create a new event loop.\n', '\n', '        You must call set_event_loop() to make this the current event\n', '        loop.\n', '        """\n', '        return self._loop_factory()\n', '\n', '\n', '# Event loop policy.  The policy itself is always global, even if the\n', "# policy's rules say that there is an event loop per thread (or other\n", '# notion of context).  The default policy is installed by the first\n', '# call to get_event_loop_policy().\n', '_event_loop_policy = None\n', '\n', '# Lock for protecting the on-the-fly creation of the event loop policy.\n', '_lock = threading.Lock()\n', '\n', '\n', '# A TLS for the running event loop, used by _get_running_loop.\n', 'class _RunningLoop(threading.local):\n', '    loop_pid = (None, None)\n', '\n', '\n', '_running_loop = _RunningLoop()\n', '\n', '\n', 'def get_running_loop():\n', '    """Return the running event loop.  Raise a RuntimeError if there is none.\n', '\n', '    This function is thread-specific.\n', '    """\n', '    # NOTE: this function is implemented in C (see _asynciomodule.c)\n', '    loop = _get_running_loop()\n', '    if loop is None:\n', "        raise RuntimeError('no running event loop')\n", '    return loop\n', '\n', '\n', 'def _get_running_loop():\n', '    """Return the running event loop or None.\n', '\n', '    This is a low-level function intended to be used by event loops.\n', '    This function is thread-specific.\n', '    """\n', '    # NOTE: this function is implemented in C (see _asynciomodule.c)\n', '    running_loop, pid = _running_loop.loop_pid\n', '    if running_loop is not None and pid == os.getpid():\n', '        return running_loop\n', '\n', '\n', 'def _set_running_loop(loop):\n', '    """Set the running event loop.\n', '\n', '    This is a low-level function intended to be used by event loops.\n', '    This function is thread-specific.\n', '    """\n', '    # NOTE: this function is implemented in C (see _asynciomodule.c)\n', '    _running_loop.loop_pid = (loop, os.getpid())\n', '\n', '\n', 'def _init_event_loop_policy():\n', '    global _event_loop_policy\n', '    with _lock:\n', '        if _event_loop_policy is None:  # pragma: no branch\n', '            from . import DefaultEventLoopPolicy\n', '            _event_loop_policy = DefaultEventLoopPolicy()\n', '\n', '\n', 'def get_event_loop_policy():\n', '    """Get the current event loop policy."""\n', '    if _event_loop_policy is None:\n', '        _init_event_loop_policy()\n', '    return _event_loop_policy\n', '\n', '\n', 'def set_event_loop_policy(policy):\n', '    """Set the current event loop policy.\n', '\n', '    If policy is None, the default policy is restored."""\n', '    global _event_loop_policy\n', '    assert policy is None or isinstance(policy, AbstractEventLoopPolicy)\n', '    _event_loop_policy = policy\n', '\n', '\n', 'def get_event_loop():\n', '    """Return an asyncio event loop.\n', '\n', '    When called from a coroutine or a callback (e.g. scheduled with call_soon\n', '    or similar API), this function will always return the running event loop.\n', '\n', '    If there is no running event loop set, the function will return\n', '    the result of `get_event_loop_policy().get_event_loop()` call.\n', '    """\n', '    # NOTE: this function is implemented in C (see _asynciomodule.c)\n', '    return _py__get_event_loop()\n', '\n', '\n', 'def _get_event_loop(stacklevel=3):\n', '    current_loop = _get_running_loop()\n', '    if current_loop is not None:\n', '        return current_loop\n', '    import warnings\n', "    warnings.warn('There is no current event loop',\n", '                  DeprecationWarning, stacklevel=stacklevel)\n', '    return get_event_loop_policy().get_event_loop()\n', '\n', '\n', 'def set_event_loop(loop):\n', '    """Equivalent to calling get_event_loop_policy().set_event_loop(loop)."""\n', '    get_event_loop_policy().set_event_loop(loop)\n', '\n', '\n', 'def new_event_loop():\n', '    """Equivalent to calling get_event_loop_policy().new_event_loop()."""\n', '    return get_event_loop_policy().new_event_loop()\n', '\n', '\n', 'def get_child_watcher():\n', '    """Equivalent to calling get_event_loop_policy().get_child_watcher()."""\n', '    return get_event_loop_policy().get_child_watcher()\n', '\n', '\n', 'def set_child_watcher(watcher):\n', '    """Equivalent to calling\n', '    get_event_loop_policy().set_child_watcher(watcher)."""\n', '    return get_event_loop_policy().set_child_watcher(watcher)\n', '\n', '\n', '# Alias pure-Python implementations for testing purposes.\n', '_py__get_running_loop = _get_running_loop\n', '_py__set_running_loop = _set_running_loop\n', '_py_get_running_loop = get_running_loop\n', '_py_get_event_loop = get_event_loop\n', '_py__get_event_loop = _get_event_loop\n', '\n', '\n', 'try:\n', '    # get_event_loop() is one of the most frequently called\n', '    # functions in asyncio.  Pure Python implementation is\n', '    # about 4 times slower than C-accelerated.\n', '    from _asyncio import (_get_running_loop, _set_running_loop,\n', '                          get_running_loop, get_event_loop, _get_event_loop)\n', 'except ImportError:\n', '    pass\n', 'else:\n', '    # Alias C implementations for testing purposes.\n', '    _c__get_running_loop = _get_running_loop\n', '    _c__set_running_loop = _set_running_loop\n', '    _c_get_running_loop = get_running_loop\n', '    _c_get_event_loop = get_event_loop\n', '    _c__get_event_loop = _get_event_loop\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/events.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/kindergarten.py': (1099, 1.0, ['from .config import Config\n', 'from .server import Server\n', '\n', 'import asyncio\n', 'import json\n', 'import logging\n', 'import signal\n', 'import sys\n', '\n', 'log = logging.getLogger("amethyst.kindergarten")\n', '\n', '\n', 'class ServerManager:\n', '    def __init__(self, config_path):\n', '        self.config_path = config_path\n', '        self.config = Config.from_config(self._get_config())\n', '        self.server = Server(self.config)\n', '\n', '    def _get_config(self):\n', '        with open(self.config_path) as f:\n', '            return json.load(f)\n', '\n', '    def reconfigure(self):\n', '        log.info("Received HUP; reloading configuration.")\n', '\n', '        self.config.load(self._get_config())\n', '\n', '        for host in self.config.hosts:\n', '            host.tls.clear_context_cache()\n', '\n', '    def start(self):\n', '        loop = asyncio.get_event_loop()\n', '        loop.add_signal_handler(signal.SIGHUP, self.reconfigure)\n', '\n', '        log.info(f"Starting server on port {self.config.port}")\n', '\n', '        loop.run_until_complete(self.server.server)\n', '        loop.run_forever()\n', '\n', '\n', 'def cli():\n', '    logging.basicConfig(level=logging.INFO)\n', '    ServerManager(sys.argv[1]).start()\n', '\n', '\n', 'if __name__ == "__main__":\n', '    cli()\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/kindergarten.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/bin/.amethyst-wrapped': (990, 1.0, ['#!/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/bin/python3.10\n', '# -*- coding: utf-8 -*-\n', "import sys;import site;import functools;sys.argv[0] = '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/bin/amethyst';functools.reduce(lambda k, p: site.addsitedir(p, k), ['/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages','/nix/store/90gmnpw25sgpv6wyvcs34g941a7mwfy0-python3.10-cryptography-38.0.1/lib/python3.10/site-packages','/nix/store/vsfwiwh1cdgy9f27wmjg6mjhn9lq75qm-python3.10-cffi-1.15.1/lib/python3.10/site-packages','/nix/store/s3qb5w2ciqhbrr460hy2g3djqpycxd6z-python3.10-pycparser-2.21/lib/python3.10/site-packages','/nix/store/lsvw498hh26fv6kdp8x1khlc60j6fc39-python3.10-amethyst_extensions-0.0.1/lib/python3.10/site-packages'], site._init_pathinfo());\n", 'import re\n', 'import sys\n', 'from amethyst.kindergarten import cli\n', "if __name__ == '__main__':\n", "    sys.argv[0] = re.sub(r'(-script\\.pyw|\\.exe)?


, '', sys.argv[0])\n", '    sys.exit(cli())\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/bin/.amethyst-wrapped'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/ast.py': (59656, 1.0, ['"""\n', '    ast\n', '    ~~~\n', '\n', '    The `ast` module helps Python applications to process trees of the Python\n', '    abstract syntax grammar.  The abstract syntax itself might change with\n', '    each Python release; this module helps to find out programmatically what\n', '    the current grammar looks like and allows modifications of it.\n', '\n', '    An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as\n', '    a flag to the `compile()` builtin function or by using the `parse()`\n', '    function from this module.  The result will be a tree of objects whose\n', '    classes all inherit from `ast.AST`.\n', '\n', '    A modified abstract syntax tree can be compiled into a Python code object\n', '    using the built-in `compile()` function.\n', '\n', '    Additionally various helper functions are provided that make working with\n', '    the trees simpler.  The main intention of the helper functions and this\n', '    module in general is to provide an easy to use interface for libraries\n', '    that work tightly with the python syntax (template engines for example).\n', '\n', '\n', '    :copyright: Copyright 2008 by Armin Ronacher.\n', '    :license: Python License.\n', '"""\n', 'import sys\n', 'from _ast import *\n', 'from contextlib import contextmanager, nullcontext\n', 'from enum import IntEnum, auto\n', '\n', '\n', "def parse(source, filename='<unknown>', mode='exec', *,\n", '          type_comments=False, feature_version=None):\n', '    """\n', '    Parse the source into an AST node.\n', '    Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).\n', '    Pass type_comments=True to get back type comments where the syntax allows.\n', '    """\n', '    flags = PyCF_ONLY_AST\n', '    if type_comments:\n', '        flags |= PyCF_TYPE_COMMENTS\n', '    if isinstance(feature_version, tuple):\n', '        major, minor = feature_version  # Should be a 2-tuple.\n', '        assert major == 3\n', '        feature_version = minor\n', '    elif feature_version is None:\n', '        feature_version = -1\n', '    # Else it should be an int giving the minor version for 3.x.\n', '    return compile(source, filename, mode, flags,\n', '                   _feature_version=feature_version)\n', '\n', '\n', 'def literal_eval(node_or_string):\n', '    """\n', '    Evaluate an expression node or a string containing only a Python\n', '    expression.  The string or node provided may only consist of the following\n', '    Python literal structures: strings, bytes, numbers, tuples, lists, dicts,\n', '    sets, booleans, and None.\n', '\n', '    Caution: A complex expression can overflow the C stack and cause a crash.\n', '    """\n', '    if isinstance(node_or_string, str):\n', '        node_or_string = parse(node_or_string.lstrip(" \\t"), mode=\'eval\')\n', '    if isinstance(node_or_string, Expression):\n', '        node_or_string = node_or_string.body\n', '    def _raise_malformed_node(node):\n', '        msg = "malformed node or string"\n', "        if lno := getattr(node, 'lineno', None):\n", "            msg += f' on line {lno}'\n", "        raise ValueError(msg + f': {node!r}')\n", '    def _convert_num(node):\n', '        if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):\n', '            _raise_malformed_node(node)\n', '        return node.value\n', '    def _convert_signed_num(node):\n', '        if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):\n', '            operand = _convert_num(node.operand)\n', '            if isinstance(node.op, UAdd):\n', '                return + operand\n', '            else:\n', '                return - operand\n', '        return _convert_num(node)\n', '    def _convert(node):\n', '        if isinstance(node, Constant):\n', '            return node.value\n', '        elif isinstance(node, Tuple):\n', '            return tuple(map(_convert, node.elts))\n', '        elif isinstance(node, List):\n', '            return list(map(_convert, node.elts))\n', '        elif isinstance(node, Set):\n', '            return set(map(_convert, node.elts))\n', '        elif (isinstance(node, Call) and isinstance(node.func, Name) and\n', "              node.func.id == 'set' and node.args == node.keywords == []):\n", '            return set()\n', '        elif isinstance(node, Dict):\n', '            if len(node.keys) != len(node.values):\n', '                _raise_malformed_node(node)\n', '            return dict(zip(map(_convert, node.keys),\n', '                            map(_convert, node.values)))\n', '        elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):\n', '            left = _convert_signed_num(node.left)\n', '            right = _convert_num(node.right)\n', '            if isinstance(left, (int, float)) and isinstance(right, complex):\n', '                if isinstance(node.op, Add):\n', '                    return left + right\n', '                else:\n', '                    return left - right\n', '        return _convert_signed_num(node)\n', '    return _convert(node_or_string)\n', '\n', '\n', 'def dump(node, annotate_fields=True, include_attributes=False, *, indent=None):\n', '    """\n', '    Return a formatted dump of the tree in node.  This is mainly useful for\n', '    debugging purposes.  If annotate_fields is true (by default),\n', '    the returned string will show the names and the values for fields.\n', '    If annotate_fields is false, the result string will be more compact by\n', '    omitting unambiguous field names.  Attributes such as line\n', '    numbers and column offsets are not dumped by default.  If this is wanted,\n', '    include_attributes can be set to true.  If indent is a non-negative\n', '    integer or string, then the tree will be pretty-printed with that indent\n', '    level. None (the default) selects the single line representation.\n', '    """\n', '    def _format(node, level=0):\n', '        if indent is not None:\n', '            level += 1\n', "            prefix = '\\n' + indent * level\n", "            sep = ',\\n' + indent * level\n", '        else:\n', "            prefix = ''\n", "            sep = ', '\n", '        if isinstance(node, AST):\n', '            cls = type(node)\n', '            args = []\n', '            allsimple = True\n', '            keywords = annotate_fields\n', '            for name in node._fields:\n', '                try:\n', '                    value = getattr(node, name)\n', '                except AttributeError:\n', '                    keywords = True\n', '                    continue\n', '                if value is None and getattr(cls, name, ...) is None:\n', '                    keywords = True\n', '                    continue\n', '                value, simple = _format(value, level)\n', '                allsimple = allsimple and simple\n', '                if keywords:\n', "                    args.append('%s=%s' % (name, value))\n", '                else:\n', '                    args.append(value)\n', '            if include_attributes and node._attributes:\n', '                for name in node._attributes:\n', '                    try:\n', '                        value = getattr(node, name)\n', '                    except AttributeError:\n', '                        continue\n', '                    if value is None and getattr(cls, name, ...) is None:\n', '                        continue\n', '                    value, simple = _format(value, level)\n', '                    allsimple = allsimple and simple\n', "                    args.append('%s=%s' % (name, value))\n", '            if allsimple and len(args) <= 3:\n', "                return '%s(%s)' % (node.__class__.__name__, ', '.join(args)), not args\n", "            return '%s(%s%s)' % (node.__class__.__name__, prefix, sep.join(args)), False\n", '        elif isinstance(node, list):\n', '            if not node:\n', "                return '[]', True\n", "            return '[%s%s]' % (prefix, sep.join(_format(x, level)[0] for x in node)), False\n", '        return repr(node), True\n', '\n', '    if not isinstance(node, AST):\n', "        raise TypeError('expected AST, got %r' % node.__class__.__name__)\n", '    if indent is not None and not isinstance(indent, str):\n', "        indent = ' ' * indent\n", '    return _format(node)[0]\n', '\n', '\n', 'def copy_location(new_node, old_node):\n', '    """\n', '    Copy source location (`lineno`, `col_offset`, `end_lineno`, and `end_col_offset`\n', '    attributes) from *old_node* to *new_node* if possible, and return *new_node*.\n', '    """\n', "    for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':\n", '        if attr in old_node._attributes and attr in new_node._attributes:\n', '            value = getattr(old_node, attr, None)\n', '            # end_lineno and end_col_offset are optional attributes, and they\n', '            # should be copied whether the value is None or not.\n', '            if value is not None or (\n', '                hasattr(old_node, attr) and attr.startswith("end_")\n', '            ):\n', '                setattr(new_node, attr, value)\n', '    return new_node\n', '\n', '\n', 'def fix_missing_locations(node):\n', '    """\n', '    When you compile a node tree with compile(), the compiler expects lineno and\n', '    col_offset attributes for every node that supports them.  This is rather\n', '    tedious to fill in for generated nodes, so this helper adds these attributes\n', '    recursively where not already set, by setting them to the values of the\n', '    parent node.  It works recursively starting at *node*.\n', '    """\n', '    def _fix(node, lineno, col_offset, end_lineno, end_col_offset):\n', "        if 'lineno' in node._attributes:\n", "            if not hasattr(node, 'lineno'):\n", '                node.lineno = lineno\n', '            else:\n', '                lineno = node.lineno\n', "        if 'end_lineno' in node._attributes:\n", "            if getattr(node, 'end_lineno', None) is None:\n", '                node.end_lineno = end_lineno\n', '            else:\n', '                end_lineno = node.end_lineno\n', "        if 'col_offset' in node._attributes:\n", "            if not hasattr(node, 'col_offset'):\n", '                node.col_offset = col_offset\n', '            else:\n', '                col_offset = node.col_offset\n', "        if 'end_col_offset' in node._attributes:\n", "            if getattr(node, 'end_col_offset', None) is None:\n", '                node.end_col_offset = end_col_offset\n', '            else:\n', '                end_col_offset = node.end_col_offset\n', '        for child in iter_child_nodes(node):\n', '            _fix(child, lineno, col_offset, end_lineno, end_col_offset)\n', '    _fix(node, 1, 0, 1, 0)\n', '    return node\n', '\n', '\n', 'def increment_lineno(node, n=1):\n', '    """\n', '    Increment the line number and end line number of each node in the tree\n', '    starting at *node* by *n*. This is useful to "move code" to a different\n', '    location in a file.\n', '    """\n', '    for child in walk(node):\n', "        if 'lineno' in child._attributes:\n", "            child.lineno = getattr(child, 'lineno', 0) + n\n", '        if (\n', '            "end_lineno" in child._attributes\n', '            and (end_lineno := getattr(child, "end_lineno", 0)) is not None\n', '        ):\n', '            child.end_lineno = end_lineno + n\n', '    return node\n', '\n', '\n', 'def iter_fields(node):\n', '    """\n', '    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``\n', '    that is present on *node*.\n', '    """\n', '    for field in node._fields:\n', '        try:\n', '            yield field, getattr(node, field)\n', '        except AttributeError:\n', '            pass\n', '\n', '\n', 'def iter_child_nodes(node):\n', '    """\n', '    Yield all direct child nodes of *node*, that is, all fields that are nodes\n', '    and all items of fields that are lists of nodes.\n', '    """\n', '    for name, field in iter_fields(node):\n', '        if isinstance(field, AST):\n', '            yield field\n', '        elif isinstance(field, list):\n', '            for item in field:\n', '                if isinstance(item, AST):\n', '                    yield item\n', '\n', '\n', 'def get_docstring(node, clean=True):\n', '    """\n', '    Return the docstring for the given node or None if no docstring can\n', '    be found.  If the node provided does not have docstrings a TypeError\n', '    will be raised.\n', '\n', '    If *clean* is `True`, all tabs are expanded to spaces and any whitespace\n', '    that can be uniformly removed from the second line onwards is removed.\n', '    """\n', '    if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):\n', '        raise TypeError("%r can\'t have docstrings" % node.__class__.__name__)\n', '    if not(node.body and isinstance(node.body[0], Expr)):\n', '        return None\n', '    node = node.body[0].value\n', '    if isinstance(node, Str):\n', '        text = node.s\n', '    elif isinstance(node, Constant) and isinstance(node.value, str):\n', '        text = node.value\n', '    else:\n', '        return None\n', '    if clean:\n', '        import inspect\n', '        text = inspect.cleandoc(text)\n', '    return text\n', '\n', '\n', 'def _splitlines_no_ff(source):\n', '    """Split a string into lines ignoring form feed and other chars.\n', '\n', '    This mimics how the Python parser splits source code.\n', '    """\n', '    idx = 0\n', '    lines = []\n', "    next_line = ''\n", '    while idx < len(source):\n', '        c = source[idx]\n', '        next_line += c\n', '        idx += 1\n', '        # Keep \\r\\n together\n', "        if c == '\\r' and idx < len(source) and source[idx] == '\\n':\n", "            next_line += '\\n'\n", '            idx += 1\n', "        if c in '\\r\\n':\n", '            lines.append(next_line)\n', "            next_line = ''\n", '\n', '    if next_line:\n', '        lines.append(next_line)\n', '    return lines\n', '\n', '\n', 'def _pad_whitespace(source):\n', '    r"""Replace all chars except \'\\f\\t\' in a line with spaces."""\n', "    result = ''\n", '    for c in source:\n', "        if c in '\\f\\t':\n", '            result += c\n', '        else:\n', "            result += ' '\n", '    return result\n', '\n', '\n', 'def get_source_segment(source, node, *, padded=False):\n', '    """Get source code segment of the *source* that generated *node*.\n', '\n', '    If some location information (`lineno`, `end_lineno`, `col_offset`,\n', '    or `end_col_offset`) is missing, return None.\n', '\n', '    If *padded* is `True`, the first line of a multi-line statement will\n', '    be padded with spaces to match its original position.\n', '    """\n', '    try:\n', '        if node.end_lineno is None or node.end_col_offset is None:\n', '            return None\n', '        lineno = node.lineno - 1\n', '        end_lineno = node.end_lineno - 1\n', '        col_offset = node.col_offset\n', '        end_col_offset = node.end_col_offset\n', '    except AttributeError:\n', '        return None\n', '\n', '    lines = _splitlines_no_ff(source)\n', '    if end_lineno == lineno:\n', '        return lines[lineno].encode()[col_offset:end_col_offset].decode()\n', '\n', '    if padded:\n', '        padding = _pad_whitespace(lines[lineno].encode()[:col_offset].decode())\n', '    else:\n', "        padding = ''\n", '\n', '    first = padding + lines[lineno].encode()[col_offset:].decode()\n', '    last = lines[end_lineno].encode()[:end_col_offset].decode()\n', '    lines = lines[lineno+1:end_lineno]\n', '\n', '    lines.insert(0, first)\n', '    lines.append(last)\n', "    return ''.join(lines)\n", '\n', '\n', 'def walk(node):\n', '    """\n', '    Recursively yield all descendant nodes in the tree starting at *node*\n', '    (including *node* itself), in no specified order.  This is useful if you\n', "    only want to modify nodes in place and don't care about the context.\n", '    """\n', '    from collections import deque\n', '    todo = deque([node])\n', '    while todo:\n', '        node = todo.popleft()\n', '        todo.extend(iter_child_nodes(node))\n', '        yield node\n', '\n', '\n', 'class NodeVisitor(object):\n', '    """\n', '    A node visitor base class that walks the abstract syntax tree and calls a\n', '    visitor function for every node found.  This function may return a value\n', '    which is forwarded by the `visit` method.\n', '\n', '    This class is meant to be subclassed, with the subclass adding visitor\n', '    methods.\n', '\n', "    Per default the visitor functions for the nodes are ``'visit_'`` +\n", '    class name of the node.  So a `TryFinally` node visit function would\n', '    be `visit_TryFinally`.  This behavior can be changed by overriding\n', '    the `visit` method.  If no visitor function exists for a node\n', '    (return value `None`) the `generic_visit` visitor is used instead.\n', '\n', "    Don't use the `NodeVisitor` if you want to apply changes to nodes during\n", '    traversing.  For this a special visitor exists (`NodeTransformer`) that\n', '    allows modifications.\n', '    """\n', '\n', '    def visit(self, node):\n', '        """Visit a node."""\n', "        method = 'visit_' + node.__class__.__name__\n", '        visitor = getattr(self, method, self.generic_visit)\n', '        return visitor(node)\n', '\n', '    def generic_visit(self, node):\n', '        """Called if no explicit visitor function exists for a node."""\n', '        for field, value in iter_fields(node):\n', '            if isinstance(value, list):\n', '                for item in value:\n', '                    if isinstance(item, AST):\n', '                        self.visit(item)\n', '            elif isinstance(value, AST):\n', '                self.visit(value)\n', '\n', '    def visit_Constant(self, node):\n', '        value = node.value\n', '        type_name = _const_node_type_names.get(type(value))\n', '        if type_name is None:\n', '            for cls, name in _const_node_type_names.items():\n', '                if isinstance(value, cls):\n', '                    type_name = name\n', '                    break\n', '        if type_name is not None:\n', "            method = 'visit_' + type_name\n", '            try:\n', '                visitor = getattr(self, method)\n', '            except AttributeError:\n', '                pass\n', '            else:\n', '                import warnings\n', '                warnings.warn(f"{method} is deprecated; add visit_Constant",\n', '                              DeprecationWarning, 2)\n', '                return visitor(node)\n', '        return self.generic_visit(node)\n', '\n', '\n', 'class NodeTransformer(NodeVisitor):\n', '    """\n', '    A :class:`NodeVisitor` subclass that walks the abstract syntax tree and\n', '    allows modification of nodes.\n', '\n', '    The `NodeTransformer` will walk the AST and use the return value of the\n', '    visitor methods to replace or remove the old node.  If the return value of\n', '    the visitor method is ``None``, the node will be removed from its location,\n', '    otherwise it is replaced with the return value.  The return value may be the\n', '    original node in which case no replacement takes place.\n', '\n', '    Here is an example transformer that rewrites all occurrences of name lookups\n', "    (``foo``) to ``data['foo']``::\n", '\n', '       class RewriteName(NodeTransformer):\n', '\n', '           def visit_Name(self, node):\n', '               return Subscript(\n', "                   value=Name(id='data', ctx=Load()),\n", '                   slice=Constant(value=node.id),\n', '                   ctx=node.ctx\n', '               )\n', '\n', "    Keep in mind that if the node you're operating on has child nodes you must\n", '    either transform the child nodes yourself or call the :meth:`generic_visit`\n', '    method for the node first.\n', '\n', '    For nodes that were part of a collection of statements (that applies to all\n', '    statement nodes), the visitor may also return a list of nodes rather than\n', '    just a single node.\n', '\n', '    Usually you use the transformer like this::\n', '\n', '       node = YourTransformer().visit(node)\n', '    """\n', '\n', '    def generic_visit(self, node):\n', '        for field, old_value in iter_fields(node):\n', '            if isinstance(old_value, list):\n', '                new_values = []\n', '                for value in old_value:\n', '                    if isinstance(value, AST):\n', '                        value = self.visit(value)\n', '                        if value is None:\n', '                            continue\n', '                        elif not isinstance(value, AST):\n', '                            new_values.extend(value)\n', '                            continue\n', '                    new_values.append(value)\n', '                old_value[:] = new_values\n', '            elif isinstance(old_value, AST):\n', '                new_node = self.visit(old_value)\n', '                if new_node is None:\n', '                    delattr(node, field)\n', '                else:\n', '                    setattr(node, field, new_node)\n', '        return node\n', '\n', '\n', '# If the ast module is loaded more than once, only add deprecated methods once\n', "if not hasattr(Constant, 'n'):\n", '    # The following code is for backward compatibility.\n', '    # It will be removed in future.\n', '\n', '    def _getter(self):\n', '        """Deprecated. Use value instead."""\n', '        return self.value\n', '\n', '    def _setter(self, value):\n', '        self.value = value\n', '\n', '    Constant.n = property(_getter, _setter)\n', '    Constant.s = property(_getter, _setter)\n', '\n', 'class _ABC(type):\n', '\n', '    def __init__(cls, *args):\n', '        cls.__doc__ = """Deprecated AST node class. Use ast.Constant instead"""\n', '\n', '    def __instancecheck__(cls, inst):\n', '        if not isinstance(inst, Constant):\n', '            return False\n', '        if cls in _const_types:\n', '            try:\n', '                value = inst.value\n', '            except AttributeError:\n', '                return False\n', '            else:\n', '                return (\n', '                    isinstance(value, _const_types[cls]) and\n', '                    not isinstance(value, _const_types_not.get(cls, ()))\n', '                )\n', '        return type.__instancecheck__(cls, inst)\n', '\n', 'def _new(cls, *args, **kwargs):\n', '    for key in kwargs:\n', '        if key not in cls._fields:\n', '            # arbitrary keyword arguments are accepted\n', '            continue\n', '        pos = cls._fields.index(key)\n', '        if pos < len(args):\n', '            raise TypeError(f"{cls.__name__} got multiple values for argument {key!r}")\n', '    if cls in _const_types:\n', '        return Constant(*args, **kwargs)\n', '    return Constant.__new__(cls, *args, **kwargs)\n', '\n', 'class Num(Constant, metaclass=_ABC):\n', "    _fields = ('n',)\n", '    __new__ = _new\n', '\n', 'class Str(Constant, metaclass=_ABC):\n', "    _fields = ('s',)\n", '    __new__ = _new\n', '\n', 'class Bytes(Constant, metaclass=_ABC):\n', "    _fields = ('s',)\n", '    __new__ = _new\n', '\n', 'class NameConstant(Constant, metaclass=_ABC):\n', '    __new__ = _new\n', '\n', 'class Ellipsis(Constant, metaclass=_ABC):\n', '    _fields = ()\n', '\n', '    def __new__(cls, *args, **kwargs):\n', '        if cls is Ellipsis:\n', '            return Constant(..., *args, **kwargs)\n', '        return Constant.__new__(cls, *args, **kwargs)\n', '\n', '_const_types = {\n', '    Num: (int, float, complex),\n', '    Str: (str,),\n', '    Bytes: (bytes,),\n', '    NameConstant: (type(None), bool),\n', '    Ellipsis: (type(...),),\n', '}\n', '_const_types_not = {\n', '    Num: (bool,),\n', '}\n', '\n', '_const_node_type_names = {\n', "    bool: 'NameConstant',  # should be before int\n", "    type(None): 'NameConstant',\n", "    int: 'Num',\n", "    float: 'Num',\n", "    complex: 'Num',\n", "    str: 'Str',\n", "    bytes: 'Bytes',\n", "    type(...): 'Ellipsis',\n", '}\n', '\n', 'class slice(AST):\n', '    """Deprecated AST node class."""\n', '\n', 'class Index(slice):\n', '    """Deprecated AST node class. Use the index value directly instead."""\n', '    def __new__(cls, value, **kwargs):\n', '        return value\n', '\n', 'class ExtSlice(slice):\n', '    """Deprecated AST node class. Use ast.Tuple instead."""\n', '    def __new__(cls, dims=(), **kwargs):\n', '        return Tuple(list(dims), Load(), **kwargs)\n', '\n', '# If the ast module is loaded more than once, only add deprecated methods once\n', "if not hasattr(Tuple, 'dims'):\n", '    # The following code is for backward compatibility.\n', '    # It will be removed in future.\n', '\n', '    def _dims_getter(self):\n', '        """Deprecated. Use elts instead."""\n', '        return self.elts\n', '\n', '    def _dims_setter(self, value):\n', '        self.elts = value\n', '\n', '    Tuple.dims = property(_dims_getter, _dims_setter)\n', '\n', 'class Suite(mod):\n', '    """Deprecated AST node class.  Unused in Python 3."""\n', '\n', 'class AugLoad(expr_context):\n', '    """Deprecated AST node class.  Unused in Python 3."""\n', '\n', 'class AugStore(expr_context):\n', '    """Deprecated AST node class.  Unused in Python 3."""\n', '\n', 'class Param(expr_context):\n', '    """Deprecated AST node class.  Unused in Python 3."""\n', '\n', '\n', '# Large float and imaginary literals get turned into infinities in the AST.\n', '# We unparse those infinities to INFSTR.\n', '_INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)\n', '\n', 'class _Precedence(IntEnum):\n', '    """Precedence table that originated from python grammar."""\n', '\n', '    TUPLE = auto()\n', "    YIELD = auto()           # 'yield', 'yield from'\n", "    TEST = auto()            # 'if'-'else', 'lambda'\n", "    OR = auto()              # 'or'\n", "    AND = auto()             # 'and'\n", "    NOT = auto()             # 'not'\n", "    CMP = auto()             # '<', '>', '==', '>=', '<=', '!=',\n", "                             # 'in', 'not in', 'is', 'is not'\n", '    EXPR = auto()\n', "    BOR = EXPR               # '|'\n", "    BXOR = auto()            # '^'\n", "    BAND = auto()            # '&'\n", "    SHIFT = auto()           # '<<', '>>'\n", "    ARITH = auto()           # '+', '-'\n", "    TERM = auto()            # '*', '@', '/', '%', '//'\n", "    FACTOR = auto()          # unary '+', '-', '~'\n", "    POWER = auto()           # '**'\n", "    AWAIT = auto()           # 'await'\n", '    ATOM = auto()\n', '\n', '    def next(self):\n', '        try:\n', '            return self.__class__(self + 1)\n', '        except ValueError:\n', '            return self\n', '\n', '\n', '_SINGLE_QUOTES = ("\'", \'"\')\n', '_MULTI_QUOTES = (\'"""\', "\'\'\'")\n', '_ALL_QUOTES = (*_SINGLE_QUOTES, *_MULTI_QUOTES)\n', '\n', 'class _Unparser(NodeVisitor):\n', '    """Methods in this class recursively traverse an AST and\n', '    output source code for the abstract syntax; original formatting\n', '    is disregarded."""\n', '\n', '    def __init__(self, *, _avoid_backslashes=False):\n', '        self._source = []\n', '        self._buffer = []\n', '        self._precedences = {}\n', '        self._type_ignores = {}\n', '        self._indent = 0\n', '        self._avoid_backslashes = _avoid_backslashes\n', '\n', '    def interleave(self, inter, f, seq):\n', '        """Call f on each item in seq, calling inter() in between."""\n', '        seq = iter(seq)\n', '        try:\n', '            f(next(seq))\n', '        except StopIteration:\n', '            pass\n', '        else:\n', '            for x in seq:\n', '                inter()\n', '                f(x)\n', '\n', '    def items_view(self, traverser, items):\n', '        """Traverse and separate the given *items* with a comma and append it to\n', '        the buffer. If *items* is a single item sequence, a trailing comma\n', '        will be added."""\n', '        if len(items) == 1:\n', '            traverser(items[0])\n', '            self.write(",")\n', '        else:\n', '            self.interleave(lambda: self.write(", "), traverser, items)\n', '\n', '    def maybe_newline(self):\n', '        """Adds a newline if it isn\'t the start of generated source"""\n', '        if self._source:\n', '            self.write("\\n")\n', '\n', '    def fill(self, text=""):\n', '        """Indent a piece of text and append it, according to the current\n', '        indentation level"""\n', '        self.maybe_newline()\n', '        self.write("    " * self._indent + text)\n', '\n', '    def write(self, text):\n', '        """Append a piece of text"""\n', '        self._source.append(text)\n', '\n', '    def buffer_writer(self, text):\n', '        self._buffer.append(text)\n', '\n', '    @property\n', '    def buffer(self):\n', '        value = "".join(self._buffer)\n', '        self._buffer.clear()\n', '        return value\n', '\n', '    @contextmanager\n', '    def block(self, *, extra = None):\n', '        """A context manager for preparing the source for blocks. It adds\n', "        the character':', increases the indentation on enter and decreases\n", '        the indentation on exit. If *extra* is given, it will be directly\n', '        appended after the colon character.\n', '        """\n', '        self.write(":")\n', '        if extra:\n', '            self.write(extra)\n', '        self._indent += 1\n', '        yield\n', '        self._indent -= 1\n', '\n', '    @contextmanager\n', '    def delimit(self, start, end):\n', '        """A context manager for preparing the source for expressions. It adds\n', '        *start* to the buffer and enters, after exit it adds *end*."""\n', '\n', '        self.write(start)\n', '        yield\n', '        self.write(end)\n', '\n', '    def delimit_if(self, start, end, condition):\n', '        if condition:\n', '            return self.delimit(start, end)\n', '        else:\n', '            return nullcontext()\n', '\n', '    def require_parens(self, precedence, node):\n', '        """Shortcut to adding precedence related parens"""\n', '        return self.delimit_if("(", ")", self.get_precedence(node) > precedence)\n', '\n', '    def get_precedence(self, node):\n', '        return self._precedences.get(node, _Precedence.TEST)\n', '\n', '    def set_precedence(self, precedence, *nodes):\n', '        for node in nodes:\n', '            self._precedences[node] = precedence\n', '\n', '    def get_raw_docstring(self, node):\n', '        """If a docstring node is found in the body of the *node* parameter,\n', '        return that docstring node, None otherwise.\n', '\n', '        Logic mirrored from ``_PyAST_GetDocString``."""\n', '        if not isinstance(\n', '            node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)\n', '        ) or len(node.body) < 1:\n', '            return None\n', '        node = node.body[0]\n', '        if not isinstance(node, Expr):\n', '            return None\n', '        node = node.value\n', '        if isinstance(node, Constant) and isinstance(node.value, str):\n', '            return node\n', '\n', '    def get_type_comment(self, node):\n', '        comment = self._type_ignores.get(node.lineno) or node.type_comment\n', '        if comment is not None:\n', '            return f" # type: {comment}"\n', '\n', '    def traverse(self, node):\n', '        if isinstance(node, list):\n', '            for item in node:\n', '                self.traverse(item)\n', '        else:\n', '            super().visit(node)\n', '\n', '    # Note: as visit() resets the output text, do NOT rely on\n', '    # NodeVisitor.generic_visit to handle any nodes (as it calls back in to\n', '    # the subclass visit() method, which resets self._source to an empty list)\n', '    def visit(self, node):\n', '        """Outputs a source code string that, if converted back to an ast\n', '        (using ast.parse) will generate an AST equivalent to *node*"""\n', '        self._source = []\n', '        self.traverse(node)\n', '        return "".join(self._source)\n', '\n', '    def _write_docstring_and_traverse_body(self, node):\n', '        if (docstring := self.get_raw_docstring(node)):\n', '            self._write_docstring(docstring)\n', '            self.traverse(node.body[1:])\n', '        else:\n', '            self.traverse(node.body)\n', '\n', '    def visit_Module(self, node):\n', '        self._type_ignores = {\n', '            ignore.lineno: f"ignore{ignore.tag}"\n', '            for ignore in node.type_ignores\n', '        }\n', '        self._write_docstring_and_traverse_body(node)\n', '        self._type_ignores.clear()\n', '\n', '    def visit_FunctionType(self, node):\n', '        with self.delimit("(", ")"):\n', '            self.interleave(\n', '                lambda: self.write(", "), self.traverse, node.argtypes\n', '            )\n', '\n', '        self.write(" -> ")\n', '        self.traverse(node.returns)\n', '\n', '    def visit_Expr(self, node):\n', '        self.fill()\n', '        self.set_precedence(_Precedence.YIELD, node.value)\n', '        self.traverse(node.value)\n', '\n', '    def visit_NamedExpr(self, node):\n', '        with self.require_parens(_Precedence.TUPLE, node):\n', '            self.set_precedence(_Precedence.ATOM, node.target, node.value)\n', '            self.traverse(node.target)\n', '            self.write(" := ")\n', '            self.traverse(node.value)\n', '\n', '    def visit_Import(self, node):\n', '        self.fill("import ")\n', '        self.interleave(lambda: self.write(", "), self.traverse, node.names)\n', '\n', '    def visit_ImportFrom(self, node):\n', '        self.fill("from ")\n', '        self.write("." * (node.level or 0))\n', '        if node.module:\n', '            self.write(node.module)\n', '        self.write(" import ")\n', '        self.interleave(lambda: self.write(", "), self.traverse, node.names)\n', '\n', '    def visit_Assign(self, node):\n', '        self.fill()\n', '        for target in node.targets:\n', '            self.traverse(target)\n', '            self.write(" = ")\n', '        self.traverse(node.value)\n', '        if type_comment := self.get_type_comment(node):\n', '            self.write(type_comment)\n', '\n', '    def visit_AugAssign(self, node):\n', '        self.fill()\n', '        self.traverse(node.target)\n', '        self.write(" " + self.binop[node.op.__class__.__name__] + "= ")\n', '        self.traverse(node.value)\n', '\n', '    def visit_AnnAssign(self, node):\n', '        self.fill()\n', '        with self.delimit_if("(", ")", not node.simple and isinstance(node.target, Name)):\n', '            self.traverse(node.target)\n', '        self.write(": ")\n', '        self.traverse(node.annotation)\n', '        if node.value:\n', '            self.write(" = ")\n', '            self.traverse(node.value)\n', '\n', '    def visit_Return(self, node):\n', '        self.fill("return")\n', '        if node.value:\n', '            self.write(" ")\n', '            self.traverse(node.value)\n', '\n', '    def visit_Pass(self, node):\n', '        self.fill("pass")\n', '\n', '    def visit_Break(self, node):\n', '        self.fill("break")\n', '\n', '    def visit_Continue(self, node):\n', '        self.fill("continue")\n', '\n', '    def visit_Delete(self, node):\n', '        self.fill("del ")\n', '        self.interleave(lambda: self.write(", "), self.traverse, node.targets)\n', '\n', '    def visit_Assert(self, node):\n', '        self.fill("assert ")\n', '        self.traverse(node.test)\n', '        if node.msg:\n', '            self.write(", ")\n', '            self.traverse(node.msg)\n', '\n', '    def visit_Global(self, node):\n', '        self.fill("global ")\n', '        self.interleave(lambda: self.write(", "), self.write, node.names)\n', '\n', '    def visit_Nonlocal(self, node):\n', '        self.fill("nonlocal ")\n', '        self.interleave(lambda: self.write(", "), self.write, node.names)\n', '\n', '    def visit_Await(self, node):\n', '        with self.require_parens(_Precedence.AWAIT, node):\n', '            self.write("await")\n', '            if node.value:\n', '                self.write(" ")\n', '                self.set_precedence(_Precedence.ATOM, node.value)\n', '                self.traverse(node.value)\n', '\n', '    def visit_Yield(self, node):\n', '        with self.require_parens(_Precedence.YIELD, node):\n', '            self.write("yield")\n', '            if node.value:\n', '                self.write(" ")\n', '                self.set_precedence(_Precedence.ATOM, node.value)\n', '                self.traverse(node.value)\n', '\n', '    def visit_YieldFrom(self, node):\n', '        with self.require_parens(_Precedence.YIELD, node):\n', '            self.write("yield from ")\n', '            if not node.value:\n', '                raise ValueError("Node can\'t be used without a value attribute.")\n', '            self.set_precedence(_Precedence.ATOM, node.value)\n', '            self.traverse(node.value)\n', '\n', '    def visit_Raise(self, node):\n', '        self.fill("raise")\n', '        if not node.exc:\n', '            if node.cause:\n', '                raise ValueError(f"Node can\'t use cause without an exception.")\n', '            return\n', '        self.write(" ")\n', '        self.traverse(node.exc)\n', '        if node.cause:\n', '            self.write(" from ")\n', '            self.traverse(node.cause)\n', '\n', '    def visit_Try(self, node):\n', '        self.fill("try")\n', '        with self.block():\n', '            self.traverse(node.body)\n', '        for ex in node.handlers:\n', '            self.traverse(ex)\n', '        if node.orelse:\n', '            self.fill("else")\n', '            with self.block():\n', '                self.traverse(node.orelse)\n', '        if node.finalbody:\n', '            self.fill("finally")\n', '            with self.block():\n', '                self.traverse(node.finalbody)\n', '\n', '    def visit_ExceptHandler(self, node):\n', '        self.fill("except")\n', '        if node.type:\n', '            self.write(" ")\n', '            self.traverse(node.type)\n', '        if node.name:\n', '            self.write(" as ")\n', '            self.write(node.name)\n', '        with self.block():\n', '            self.traverse(node.body)\n', '\n', '    def visit_ClassDef(self, node):\n', '        self.maybe_newline()\n', '        for deco in node.decorator_list:\n', '            self.fill("@")\n', '            self.traverse(deco)\n', '        self.fill("class " + node.name)\n', '        with self.delimit_if("(", ")", condition = node.bases or node.keywords):\n', '            comma = False\n', '            for e in node.bases:\n', '                if comma:\n', '                    self.write(", ")\n', '                else:\n', '                    comma = True\n', '                self.traverse(e)\n', '            for e in node.keywords:\n', '                if comma:\n', '                    self.write(", ")\n', '                else:\n', '                    comma = True\n', '                self.traverse(e)\n', '\n', '        with self.block():\n', '            self._write_docstring_and_traverse_body(node)\n', '\n', '    def visit_FunctionDef(self, node):\n', '        self._function_helper(node, "def")\n', '\n', '    def visit_AsyncFunctionDef(self, node):\n', '        self._function_helper(node, "async def")\n', '\n', '    def _function_helper(self, node, fill_suffix):\n', '        self.maybe_newline()\n', '        for deco in node.decorator_list:\n', '            self.fill("@")\n', '            self.traverse(deco)\n', '        def_str = fill_suffix + " " + node.name\n', '        self.fill(def_str)\n', '        with self.delimit("(", ")"):\n', '            self.traverse(node.args)\n', '        if node.returns:\n', '            self.write(" -> ")\n', '            self.traverse(node.returns)\n', '        with self.block(extra=self.get_type_comment(node)):\n', '            self._write_docstring_and_traverse_body(node)\n', '\n', '    def visit_For(self, node):\n', '        self._for_helper("for ", node)\n', '\n', '    def visit_AsyncFor(self, node):\n', '        self._for_helper("async for ", node)\n', '\n', '    def _for_helper(self, fill, node):\n', '        self.fill(fill)\n', '        self.traverse(node.target)\n', '        self.write(" in ")\n', '        self.traverse(node.iter)\n', '        with self.block(extra=self.get_type_comment(node)):\n', '            self.traverse(node.body)\n', '        if node.orelse:\n', '            self.fill("else")\n', '            with self.block():\n', '                self.traverse(node.orelse)\n', '\n', '    def visit_If(self, node):\n', '        self.fill("if ")\n', '        self.traverse(node.test)\n', '        with self.block():\n', '            self.traverse(node.body)\n', '        # collapse nested ifs into equivalent elifs.\n', '        while node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], If):\n', '            node = node.orelse[0]\n', '            self.fill("elif ")\n', '            self.traverse(node.test)\n', '            with self.block():\n', '                self.traverse(node.body)\n', '        # final else\n', '        if node.orelse:\n', '            self.fill("else")\n', '            with self.block():\n', '                self.traverse(node.orelse)\n', '\n', '    def visit_While(self, node):\n', '        self.fill("while ")\n', '        self.traverse(node.test)\n', '        with self.block():\n', '            self.traverse(node.body)\n', '        if node.orelse:\n', '            self.fill("else")\n', '            with self.block():\n', '                self.traverse(node.orelse)\n', '\n', '    def visit_With(self, node):\n', '        self.fill("with ")\n', '        self.interleave(lambda: self.write(", "), self.traverse, node.items)\n', '        with self.block(extra=self.get_type_comment(node)):\n', '            self.traverse(node.body)\n', '\n', '    def visit_AsyncWith(self, node):\n', '        self.fill("async with ")\n', '        self.interleave(lambda: self.write(", "), self.traverse, node.items)\n', '        with self.block(extra=self.get_type_comment(node)):\n', '            self.traverse(node.body)\n', '\n', '    def _str_literal_helper(\n', '        self, string, *, quote_types=_ALL_QUOTES, escape_special_whitespace=False\n', '    ):\n', '        """Helper for writing string literals, minimizing escapes.\n', '        Returns the tuple (string literal to write, possible quote types).\n', '        """\n', '        def escape_char(c):\n', '            # \\n and \\t are non-printable, but we only escape them if\n', '            # escape_special_whitespace is True\n', '            if not escape_special_whitespace and c in "\\n\\t":\n', '                return c\n', '            # Always escape backslashes and other non-printable characters\n', '            if c == "\\\\" or not c.isprintable():\n', '                return c.encode("unicode_escape").decode("ascii")\n', '            return c\n', '\n', '        escaped_string = "".join(map(escape_char, string))\n', '        possible_quotes = quote_types\n', '        if "\\n" in escaped_string:\n', '            possible_quotes = [q for q in possible_quotes if q in _MULTI_QUOTES]\n', '        possible_quotes = [q for q in possible_quotes if q not in escaped_string]\n', '        if not possible_quotes:\n', "            # If there aren't any possible_quotes, fallback to using repr\n", '            # on the original string. Try to use a quote from quote_types,\n', '            # e.g., so that we use triple quotes for docstrings.\n', '            string = repr(string)\n', '            quote = next((q for q in quote_types if string[0] in q), string[0])\n', '            return string[1:-1], [quote]\n', '        if escaped_string:\n', '            # Sort so that we prefer \'\'\'"\'\'\' over """\\""""\n', '            possible_quotes.sort(key=lambda q: q[0] == escaped_string[-1])\n', "            # If we're using triple quotes and we'd need to escape a final\n", '            # quote, escape it\n', '            if possible_quotes[0][0] == escaped_string[-1]:\n', '                assert len(possible_quotes[0]) == 3\n', '                escaped_string = escaped_string[:-1] + "\\\\" + escaped_string[-1]\n', '        return escaped_string, possible_quotes\n', '\n', '    def _write_str_avoiding_backslashes(self, string, *, quote_types=_ALL_QUOTES):\n', '        """Write string literal value with a best effort attempt to avoid backslashes."""\n', '        string, quote_types = self._str_literal_helper(string, quote_types=quote_types)\n', '        quote_type = quote_types[0]\n', '        self.write(f"{quote_type}{string}{quote_type}")\n', '\n', '    def visit_JoinedStr(self, node):\n', '        self.write("f")\n', '        if self._avoid_backslashes:\n', '            self._fstring_JoinedStr(node, self.buffer_writer)\n', '            self._write_str_avoiding_backslashes(self.buffer)\n', '            return\n', '\n', "        # If we don't need to avoid backslashes globally (i.e., we only need\n", "        # to avoid them inside FormattedValues), it's cosmetically preferred\n", "        # to use escaped whitespace. That is, it's preferred to use backslashes\n", '        # for cases like: f"{x}\\n". To accomplish this, we keep track of what\n', '        # in our buffer corresponds to FormattedValues and what corresponds to\n', '        # Constant parts of the f-string, and allow escapes accordingly.\n', '        buffer = []\n', '        for value in node.values:\n', '            meth = getattr(self, "_fstring_" + type(value).__name__)\n', '            meth(value, self.buffer_writer)\n', '            buffer.append((self.buffer, isinstance(value, Constant)))\n', '        new_buffer = []\n', '        quote_types = _ALL_QUOTES\n', '        for value, is_constant in buffer:\n', '            # Repeatedly narrow down the list of possible quote_types\n', '            value, quote_types = self._str_literal_helper(\n', '                value, quote_types=quote_types,\n', '                escape_special_whitespace=is_constant\n', '            )\n', '            new_buffer.append(value)\n', '        value = "".join(new_buffer)\n', '        quote_type = quote_types[0]\n', '        self.write(f"{quote_type}{value}{quote_type}")\n', '\n', '    def visit_FormattedValue(self, node):\n', '        self.write("f")\n', '        self._fstring_FormattedValue(node, self.buffer_writer)\n', '        self._write_str_avoiding_backslashes(self.buffer)\n', '\n', '    def _fstring_JoinedStr(self, node, write):\n', '        for value in node.values:\n', '            meth = getattr(self, "_fstring_" + type(value).__name__)\n', '            meth(value, write)\n', '\n', '    def _fstring_Constant(self, node, write):\n', '        if not isinstance(node.value, str):\n', '            raise ValueError("Constants inside JoinedStr should be a string.")\n', '        value = node.value.replace("{", "{{").replace("}", "}}")\n', '        write(value)\n', '\n', '    def _fstring_FormattedValue(self, node, write):\n', '        write("{")\n', '        unparser = type(self)(_avoid_backslashes=True)\n', '        unparser.set_precedence(_Precedence.TEST.next(), node.value)\n', '        expr = unparser.visit(node.value)\n', '        if expr.startswith("{"):\n', '            write(" ")  # Separate pair of opening brackets as "{ {"\n', '        if "\\\\" in expr:\n', '            raise ValueError("Unable to avoid backslash in f-string expression part")\n', '        write(expr)\n', '        if node.conversion != -1:\n', '            conversion = chr(node.conversion)\n', '            if conversion not in "sra":\n', '                raise ValueError("Unknown f-string conversion.")\n', '            write(f"!{conversion}")\n', '        if node.format_spec:\n', '            write(":")\n', '            meth = getattr(self, "_fstring_" + type(node.format_spec).__name__)\n', '            meth(node.format_spec, write)\n', '        write("}")\n', '\n', '    def visit_Name(self, node):\n', '        self.write(node.id)\n', '\n', '    def _write_docstring(self, node):\n', '        self.fill()\n', '        if node.kind == "u":\n', '            self.write("u")\n', '        self._write_str_avoiding_backslashes(node.value, quote_types=_MULTI_QUOTES)\n', '\n', '    def _write_constant(self, value):\n', '        if isinstance(value, (float, complex)):\n', '            # Substitute overflowing decimal literal for AST infinities,\n', '            # and inf - inf for NaNs.\n', '            self.write(\n', '                repr(value)\n', '                .replace("inf", _INFSTR)\n', '                .replace("nan", f"({_INFSTR}-{_INFSTR})")\n', '            )\n', '        elif self._avoid_backslashes and isinstance(value, str):\n', '            self._write_str_avoiding_backslashes(value)\n', '        else:\n', '            self.write(repr(value))\n', '\n', '    def visit_Constant(self, node):\n', '        value = node.value\n', '        if isinstance(value, tuple):\n', '            with self.delimit("(", ")"):\n', '                self.items_view(self._write_constant, value)\n', '        elif value is ...:\n', '            self.write("...")\n', '        else:\n', '            if node.kind == "u":\n', '                self.write("u")\n', '            self._write_constant(node.value)\n', '\n', '    def visit_List(self, node):\n', '        with self.delimit("[", "]"):\n', '            self.interleave(lambda: self.write(", "), self.traverse, node.elts)\n', '\n', '    def visit_ListComp(self, node):\n', '        with self.delimit("[", "]"):\n', '            self.traverse(node.elt)\n', '            for gen in node.generators:\n', '                self.traverse(gen)\n', '\n', '    def visit_GeneratorExp(self, node):\n', '        with self.delimit("(", ")"):\n', '            self.traverse(node.elt)\n', '            for gen in node.generators:\n', '                self.traverse(gen)\n', '\n', '    def visit_SetComp(self, node):\n', '        with self.delimit("{", "}"):\n', '            self.traverse(node.elt)\n', '            for gen in node.generators:\n', '                self.traverse(gen)\n', '\n', '    def visit_DictComp(self, node):\n', '        with self.delimit("{", "}"):\n', '            self.traverse(node.key)\n', '            self.write(": ")\n', '            self.traverse(node.value)\n', '            for gen in node.generators:\n', '                self.traverse(gen)\n', '\n', '    def visit_comprehension(self, node):\n', '        if node.is_async:\n', '            self.write(" async for ")\n', '        else:\n', '            self.write(" for ")\n', '        self.set_precedence(_Precedence.TUPLE, node.target)\n', '        self.traverse(node.target)\n', '        self.write(" in ")\n', '        self.set_precedence(_Precedence.TEST.next(), node.iter, *node.ifs)\n', '        self.traverse(node.iter)\n', '        for if_clause in node.ifs:\n', '            self.write(" if ")\n', '            self.traverse(if_clause)\n', '\n', '    def visit_IfExp(self, node):\n', '        with self.require_parens(_Precedence.TEST, node):\n', '            self.set_precedence(_Precedence.TEST.next(), node.body, node.test)\n', '            self.traverse(node.body)\n', '            self.write(" if ")\n', '            self.traverse(node.test)\n', '            self.write(" else ")\n', '            self.set_precedence(_Precedence.TEST, node.orelse)\n', '            self.traverse(node.orelse)\n', '\n', '    def visit_Set(self, node):\n', '        if node.elts:\n', '            with self.delimit("{", "}"):\n', '                self.interleave(lambda: self.write(", "), self.traverse, node.elts)\n', '        else:\n', '            # `{}` would be interpreted as a dictionary literal, and\n', '            # `set` might be shadowed. Thus:\n', "            self.write('{*()}')\n", '\n', '    def visit_Dict(self, node):\n', '        def write_key_value_pair(k, v):\n', '            self.traverse(k)\n', '            self.write(": ")\n', '            self.traverse(v)\n', '\n', '        def write_item(item):\n', '            k, v = item\n', '            if k is None:\n', "                # for dictionary unpacking operator in dicts {**{'y': 2}}\n", '                # see PEP 448 for details\n', '                self.write("**")\n', '                self.set_precedence(_Precedence.EXPR, v)\n', '                self.traverse(v)\n', '            else:\n', '                write_key_value_pair(k, v)\n', '\n', '        with self.delimit("{", "}"):\n', '            self.interleave(\n', '                lambda: self.write(", "), write_item, zip(node.keys, node.values)\n', '            )\n', '\n', '    def visit_Tuple(self, node):\n', '        with self.delimit("(", ")"):\n', '            self.items_view(self.traverse, node.elts)\n', '\n', '    unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"}\n', '    unop_precedence = {\n', '        "not": _Precedence.NOT,\n', '        "~": _Precedence.FACTOR,\n', '        "+": _Precedence.FACTOR,\n', '        "-": _Precedence.FACTOR,\n', '    }\n', '\n', '    def visit_UnaryOp(self, node):\n', '        operator = self.unop[node.op.__class__.__name__]\n', '        operator_precedence = self.unop_precedence[operator]\n', '        with self.require_parens(operator_precedence, node):\n', '            self.write(operator)\n', "            # factor prefixes (+, -, ~) shouldn't be seperated\n", '            # from the value they belong, (e.g: +1 instead of + 1)\n', '            if operator_precedence is not _Precedence.FACTOR:\n', '                self.write(" ")\n', '            self.set_precedence(operator_precedence, node.operand)\n', '            self.traverse(node.operand)\n', '\n', '    binop = {\n', '        "Add": "+",\n', '        "Sub": "-",\n', '        "Mult": "*",\n', '        "MatMult": "@",\n', '        "Div": "/",\n', '        "Mod": "%",\n', '        "LShift": "<<",\n', '        "RShift": ">>",\n', '        "BitOr": "|",\n', '        "BitXor": "^",\n', '        "BitAnd": "&",\n', '        "FloorDiv": "//",\n', '        "Pow": "**",\n', '    }\n', '\n', '    binop_precedence = {\n', '        "+": _Precedence.ARITH,\n', '        "-": _Precedence.ARITH,\n', '        "*": _Precedence.TERM,\n', '        "@": _Precedence.TERM,\n', '        "/": _Precedence.TERM,\n', '        "%": _Precedence.TERM,\n', '        "<<": _Precedence.SHIFT,\n', '        ">>": _Precedence.SHIFT,\n', '        "|": _Precedence.BOR,\n', '        "^": _Precedence.BXOR,\n', '        "&": _Precedence.BAND,\n', '        "//": _Precedence.TERM,\n', '        "**": _Precedence.POWER,\n', '    }\n', '\n', '    binop_rassoc = frozenset(("**",))\n', '    def visit_BinOp(self, node):\n', '        operator = self.binop[node.op.__class__.__name__]\n', '        operator_precedence = self.binop_precedence[operator]\n', '        with self.require_parens(operator_precedence, node):\n', '            if operator in self.binop_rassoc:\n', '                left_precedence = operator_precedence.next()\n', '                right_precedence = operator_precedence\n', '            else:\n', '                left_precedence = operator_precedence\n', '                right_precedence = operator_precedence.next()\n', '\n', '            self.set_precedence(left_precedence, node.left)\n', '            self.traverse(node.left)\n', '            self.write(f" {operator} ")\n', '            self.set_precedence(right_precedence, node.right)\n', '            self.traverse(node.right)\n', '\n', '    cmpops = {\n', '        "Eq": "==",\n', '        "NotEq": "!=",\n', '        "Lt": "<",\n', '        "LtE": "<=",\n', '        "Gt": ">",\n', '        "GtE": ">=",\n', '        "Is": "is",\n', '        "IsNot": "is not",\n', '        "In": "in",\n', '        "NotIn": "not in",\n', '    }\n', '\n', '    def visit_Compare(self, node):\n', '        with self.require_parens(_Precedence.CMP, node):\n', '            self.set_precedence(_Precedence.CMP.next(), node.left, *node.comparators)\n', '            self.traverse(node.left)\n', '            for o, e in zip(node.ops, node.comparators):\n', '                self.write(" " + self.cmpops[o.__class__.__name__] + " ")\n', '                self.traverse(e)\n', '\n', '    boolops = {"And": "and", "Or": "or"}\n', '    boolop_precedence = {"and": _Precedence.AND, "or": _Precedence.OR}\n', '\n', '    def visit_BoolOp(self, node):\n', '        operator = self.boolops[node.op.__class__.__name__]\n', '        operator_precedence = self.boolop_precedence[operator]\n', '\n', '        def increasing_level_traverse(node):\n', '            nonlocal operator_precedence\n', '            operator_precedence = operator_precedence.next()\n', '            self.set_precedence(operator_precedence, node)\n', '            self.traverse(node)\n', '\n', '        with self.require_parens(operator_precedence, node):\n', '            s = f" {operator} "\n', '            self.interleave(lambda: self.write(s), increasing_level_traverse, node.values)\n', '\n', '    def visit_Attribute(self, node):\n', '        self.set_precedence(_Precedence.ATOM, node.value)\n', '        self.traverse(node.value)\n', '        # Special case: 3.__abs__() is a syntax error, so if node.value\n', '        # is an integer literal then we need to either parenthesize\n', '        # it or add an extra space to get 3 .__abs__().\n', '        if isinstance(node.value, Constant) and isinstance(node.value.value, int):\n', '            self.write(" ")\n', '        self.write(".")\n', '        self.write(node.attr)\n', '\n', '    def visit_Call(self, node):\n', '        self.set_precedence(_Precedence.ATOM, node.func)\n', '        self.traverse(node.func)\n', '        with self.delimit("(", ")"):\n', '            comma = False\n', '            for e in node.args:\n', '                if comma:\n', '                    self.write(", ")\n', '                else:\n', '                    comma = True\n', '                self.traverse(e)\n', '            for e in node.keywords:\n', '                if comma:\n', '                    self.write(", ")\n', '                else:\n', '                    comma = True\n', '                self.traverse(e)\n', '\n', '    def visit_Subscript(self, node):\n', '        def is_simple_tuple(slice_value):\n', '            # when unparsing a non-empty tuple, the parentheses can be safely\n', "            # omitted if there aren't any elements that explicitly requires\n", '            # parentheses (such as starred expressions).\n', '            return (\n', '                isinstance(slice_value, Tuple)\n', '                and slice_value.elts\n', '                and not any(isinstance(elt, Starred) for elt in slice_value.elts)\n', '            )\n', '\n', '        self.set_precedence(_Precedence.ATOM, node.value)\n', '        self.traverse(node.value)\n', '        with self.delimit("[", "]"):\n', '            if is_simple_tuple(node.slice):\n', '                self.items_view(self.traverse, node.slice.elts)\n', '            else:\n', '                self.traverse(node.slice)\n', '\n', '    def visit_Starred(self, node):\n', '        self.write("*")\n', '        self.set_precedence(_Precedence.EXPR, node.value)\n', '        self.traverse(node.value)\n', '\n', '    def visit_Ellipsis(self, node):\n', '        self.write("...")\n', '\n', '    def visit_Slice(self, node):\n', '        if node.lower:\n', '            self.traverse(node.lower)\n', '        self.write(":")\n', '        if node.upper:\n', '            self.traverse(node.upper)\n', '        if node.step:\n', '            self.write(":")\n', '            self.traverse(node.step)\n', '\n', '    def visit_Match(self, node):\n', '        self.fill("match ")\n', '        self.traverse(node.subject)\n', '        with self.block():\n', '            for case in node.cases:\n', '                self.traverse(case)\n', '\n', '    def visit_arg(self, node):\n', '        self.write(node.arg)\n', '        if node.annotation:\n', '            self.write(": ")\n', '            self.traverse(node.annotation)\n', '\n', '    def visit_arguments(self, node):\n', '        first = True\n', '        # normal arguments\n', '        all_args = node.posonlyargs + node.args\n', '        defaults = [None] * (len(all_args) - len(node.defaults)) + node.defaults\n', '        for index, elements in enumerate(zip(all_args, defaults), 1):\n', '            a, d = elements\n', '            if first:\n', '                first = False\n', '            else:\n', '                self.write(", ")\n', '            self.traverse(a)\n', '            if d:\n', '                self.write("=")\n', '                self.traverse(d)\n', '            if index == len(node.posonlyargs):\n', '                self.write(", /")\n', '\n', "        # varargs, or bare '*' if no varargs but keyword-only arguments present\n", '        if node.vararg or node.kwonlyargs:\n', '            if first:\n', '                first = False\n', '            else:\n', '                self.write(", ")\n', '            self.write("*")\n', '            if node.vararg:\n', '                self.write(node.vararg.arg)\n', '                if node.vararg.annotation:\n', '                    self.write(": ")\n', '                    self.traverse(node.vararg.annotation)\n', '\n', '        # keyword-only arguments\n', '        if node.kwonlyargs:\n', '            for a, d in zip(node.kwonlyargs, node.kw_defaults):\n', '                self.write(", ")\n', '                self.traverse(a)\n', '                if d:\n', '                    self.write("=")\n', '                    self.traverse(d)\n', '\n', '        # kwargs\n', '        if node.kwarg:\n', '            if first:\n', '                first = False\n', '            else:\n', '                self.write(", ")\n', '            self.write("**" + node.kwarg.arg)\n', '            if node.kwarg.annotation:\n', '                self.write(": ")\n', '                self.traverse(node.kwarg.annotation)\n', '\n', '    def visit_keyword(self, node):\n', '        if node.arg is None:\n', '            self.write("**")\n', '        else:\n', '            self.write(node.arg)\n', '            self.write("=")\n', '        self.traverse(node.value)\n', '\n', '    def visit_Lambda(self, node):\n', '        with self.require_parens(_Precedence.TEST, node):\n', '            self.write("lambda ")\n', '            self.traverse(node.args)\n', '            self.write(": ")\n', '            self.set_precedence(_Precedence.TEST, node.body)\n', '            self.traverse(node.body)\n', '\n', '    def visit_alias(self, node):\n', '        self.write(node.name)\n', '        if node.asname:\n', '            self.write(" as " + node.asname)\n', '\n', '    def visit_withitem(self, node):\n', '        self.traverse(node.context_expr)\n', '        if node.optional_vars:\n', '            self.write(" as ")\n', '            self.traverse(node.optional_vars)\n', '\n', '    def visit_match_case(self, node):\n', '        self.fill("case ")\n', '        self.traverse(node.pattern)\n', '        if node.guard:\n', '            self.write(" if ")\n', '            self.traverse(node.guard)\n', '        with self.block():\n', '            self.traverse(node.body)\n', '\n', '    def visit_MatchValue(self, node):\n', '        self.traverse(node.value)\n', '\n', '    def visit_MatchSingleton(self, node):\n', '        self._write_constant(node.value)\n', '\n', '    def visit_MatchSequence(self, node):\n', '        with self.delimit("[", "]"):\n', '            self.interleave(\n', '                lambda: self.write(", "), self.traverse, node.patterns\n', '            )\n', '\n', '    def visit_MatchStar(self, node):\n', '        name = node.name\n', '        if name is None:\n', '            name = "_"\n', '        self.write(f"*{name}")\n', '\n', '    def visit_MatchMapping(self, node):\n', '        def write_key_pattern_pair(pair):\n', '            k, p = pair\n', '            self.traverse(k)\n', '            self.write(": ")\n', '            self.traverse(p)\n', '\n', '        with self.delimit("{", "}"):\n', '            keys = node.keys\n', '            self.interleave(\n', '                lambda: self.write(", "),\n', '                write_key_pattern_pair,\n', '                zip(keys, node.patterns, strict=True),\n', '            )\n', '            rest = node.rest\n', '            if rest is not None:\n', '                if keys:\n', '                    self.write(", ")\n', '                self.write(f"**{rest}")\n', '\n', '    def visit_MatchClass(self, node):\n', '        self.set_precedence(_Precedence.ATOM, node.cls)\n', '        self.traverse(node.cls)\n', '        with self.delimit("(", ")"):\n', '            patterns = node.patterns\n', '            self.interleave(\n', '                lambda: self.write(", "), self.traverse, patterns\n', '            )\n', '            attrs = node.kwd_attrs\n', '            if attrs:\n', '                def write_attr_pattern(pair):\n', '                    attr, pattern = pair\n', '                    self.write(f"{attr}=")\n', '                    self.traverse(pattern)\n', '\n', '                if patterns:\n', '                    self.write(", ")\n', '                self.interleave(\n', '                    lambda: self.write(", "),\n', '                    write_attr_pattern,\n', '                    zip(attrs, node.kwd_patterns, strict=True),\n', '                )\n', '\n', '    def visit_MatchAs(self, node):\n', '        name = node.name\n', '        pattern = node.pattern\n', '        if name is None:\n', '            self.write("_")\n', '        elif pattern is None:\n', '            self.write(node.name)\n', '        else:\n', '            with self.require_parens(_Precedence.TEST, node):\n', '                self.set_precedence(_Precedence.BOR, node.pattern)\n', '                self.traverse(node.pattern)\n', '                self.write(f" as {node.name}")\n', '\n', '    def visit_MatchOr(self, node):\n', '        with self.require_parens(_Precedence.BOR, node):\n', '            self.set_precedence(_Precedence.BOR.next(), *node.patterns)\n', '            self.interleave(lambda: self.write(" | "), self.traverse, node.patterns)\n', '\n', 'def unparse(ast_obj):\n', '    unparser = _Unparser()\n', '    return unparser.visit(ast_obj)\n', '\n', '\n', 'def main():\n', '    import argparse\n', '\n', "    parser = argparse.ArgumentParser(prog='python -m ast')\n", "    parser.add_argument('infile', type=argparse.FileType(mode='rb'), nargs='?',\n", "                        default='-',\n", "                        help='the file to parse; defaults to stdin')\n", "    parser.add_argument('-m', '--mode', default='exec',\n", "                        choices=('exec', 'single', 'eval', 'func_type'),\n", "                        help='specify what kind of code must be parsed')\n", "    parser.add_argument('--no-type-comments', default=True, action='store_false',\n", '                        help="don\'t add information about type comments")\n', "    parser.add_argument('-a', '--include-attributes', action='store_true',\n", "                        help='include attributes such as line numbers and '\n", "                             'column offsets')\n", "    parser.add_argument('-i', '--indent', type=int, default=3,\n", "                        help='indentation of nodes (number of spaces)')\n", '    args = parser.parse_args()\n', '\n', '    with args.infile as infile:\n', '        source = infile.read()\n', '    tree = parse(source, args.infile.name, args.mode, type_comments=args.no_type_comments)\n', '    print(dump(tree, include_attributes=args.include_attributes, indent=args.indent))\n', '\n', "if __name__ == '__main__':\n", '    main()\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/ast.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/tls.py': (3130, 1.0, ['import datetime\n', 'import os.path\n', 'import logging\n', 'import ssl\n', 'import traceback\n', '\n', 'from cryptography import x509\n', 'from cryptography.x509.oid import NameOID\n', 'from cryptography.hazmat.primitives import hashes, serialization\n', 'from cryptography.hazmat.primitives.asymmetric import rsa\n', '\n', 'from typing import List, TYPE_CHECKING\n', '\n', 'if TYPE_CHECKING:\n', '    from .config import Config\n', '\n', '\n', 'log = logging.getLogger("amethyst.tls")\n', '\n', '\n', 'def make_partial_context():\n', '    c = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n', '    c.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1\n', '    c.options |= ssl.OP_SINGLE_DH_USE | ssl.OP_SINGLE_ECDH_USE\n', '    c.check_hostname = False\n', '    c.verify_mode = ssl.VerifyMode.CERT_OPTIONAL\n', '    return c\n', '\n', '\n', 'def make_context(cert_path: str, key_path: str):\n', '    c = make_partial_context()\n', '    c.load_cert_chain(cert_path, keyfile=key_path)\n', '    return c\n', '\n', '\n', 'def make_sni_context(config: "Config"):\n', '    def sni_callback(sock, host, _original_ctx):\n', '        for host_cfg in config.hosts:\n', '            if host_cfg.host == host:\n', '                break\n', '        else:\n', '            return ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE\n', '\n', '        try:\n', '            sock.context = host_cfg.tls.get_ssl_context()\n', '        except Exception:\n', '            log.warn(f"When setting context after SNI; {traceback.format_exc()}")\n', '\n', '    c = make_partial_context()\n', '    c.sni_callback = sni_callback\n', '    return c\n', '\n', '\n', 'def update_certificate(cert_path: str, key_path: str, hosts: List[str]):\n', '    if os.path.exists(cert_path):\n', '        with open(cert_path, "rb") as f:\n', '            cert = x509.load_pem_x509_certificate(f.read())\n', '\n', '        if cert.not_valid_after > datetime.datetime.now():\n', '            log.info("Certificate exists and is unexpired; skipping regeneration.")\n', '            return cert.not_valid_after\n', '\n', '        else:\n', '            log.info("Certificate expired; regenerating.")\n', '\n', '    else:\n', '        log.info("Certificate does not exist yet, generating one now.")\n', '\n', '    key = rsa.generate_private_key(\n', '        public_exponent=65537,\n', '        key_size=4096,\n', '    )\n', '\n', '    with open(key_path, "wb") as f:\n', '        f.write(\n', '            key.private_bytes(\n', '                encoding=serialization.Encoding.PEM,\n', '                format=serialization.PrivateFormat.TraditionalOpenSSL,\n', '                encryption_algorithm=serialization.NoEncryption(),\n', '            )\n', '        )\n', '\n', '    subject = issuer = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, hosts[0])])\n', '\n', '    cert = (\n', '        x509.CertificateBuilder()\n', '        .subject_name(subject)\n', '        .issuer_name(issuer)\n', '        .public_key(key.public_key())\n', '        .serial_number(x509.random_serial_number())\n', '        .not_valid_before(datetime.datetime.utcnow() - datetime.timedelta(days=1))\n', '        .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=30))\n', '        .add_extension(\n', '            x509.SubjectAlternativeName([x509.DNSName(host) for host in hosts]),\n', '            critical=False,\n', '        )\n', '        .sign(key, hashes.SHA256())\n', '    )\n', '\n', '    with open(cert_path, "wb") as f:\n', '        f.write(cert.public_bytes(serialization.Encoding.PEM))\n', '\n', '    log.info("Success! Certificate generated and saved.")\n', '    return cert.not_valid_after\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/tls.py'), '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/config.py': (2800, 1.0, ['import datetime\n', 'import ssl\n', '\n', 'from dataclasses import dataclass\n', 'from typing import Dict, List, Optional, Tuple\n', '\n', 'from .handler import GenericHandler, Handler\n', 'from .resource import Resource\n', 'from .resource_registry import registry\n', '\n', 'import os\n', '\n', '\n', '@dataclass\n', 'class TLSConfig:\n', '    host: str\n', '    auto: bool = False\n', '    cert_path: Optional[str] = None\n', '    key_path: Optional[str] = None\n', '\n', '    _context_cache: Optional[Tuple[datetime.datetime, ssl.SSLContext]] = None\n', '\n', '    @classmethod\n', '    def from_config(cls, host, cfg):\n', '        o = cls(host)\n', '\n', '        state = os.getenv("STATE_DIRECTORY", ".")\n', '\n', '        o.auto = cfg.get("auto", True)\n', '\n', '        o.cert_path = cfg.get("cert_path", None)\n', '        if o.cert_path is None:\n', '            o.cert_path = os.path.join(state, f"{host}.cert.pem")\n', '\n', '        o.key_path = cfg.get("key_path", None)\n', '        if o.key_path is None:\n', '            o.key_path = os.path.join(state, f"{host}.key.pem")\n', '\n', '        return o\n', '\n', '    def clear_context_cache(self):\n', '        self._context_cache = None\n', '\n', '    def get_ssl_context(self):\n', '        from . import tls\n', '\n', '        if self._context_cache is not None:\n', '            expires, context = self._context_cache\n', '\n', '            if expires is None or expires > datetime.datetime.now():\n', '                return context\n', '\n', '        if self.auto:\n', '            expires = tls.update_certificate(self.cert_path, self.key_path, [self.host])\n', '\n', '        else:\n', '            # We want to keep using a manually-specified certificate forever\n', '            # or at least until the server is restarted / HUPed.\n', '            expires = None\n', '\n', '        context = tls.make_context(self.cert_path, self.key_path)\n', '\n', '        self._context_cache = expires, context\n', '        return context\n', '\n', '\n', '@dataclass\n', 'class HostConfig:\n', '    host: str\n', '    tls: TLSConfig\n', '    path_map: Dict[str, Resource]\n', '\n', '    @classmethod\n', '    def _construct_resource(cls, cfg) -> Resource:\n', '        resource_type = cfg.pop("type", "filesystem")\n', '        return registry[resource_type](**cfg)\n', '\n', '    @classmethod\n', '    def from_config(cls, cfg):\n', '        host = cfg["name"]\n', '        tls = TLSConfig.from_config(host, cfg.get("tls", {}))\n', '        path_map = {\n', '            path: cls._construct_resource(config)\n', '            for path, config in cfg["paths"].items()\n', '        }\n', '\n', '        return cls(host, tls, path_map)\n', '\n', '\n', '@dataclass\n', 'class Config:\n', '    hosts: List[HostConfig]\n', '    handler: Handler\n', '    port: int = 1965\n', '\n', '    def load(self, cfg):\n', '        self.hosts = [HostConfig.from_config(host) for host in cfg.get("hosts", [])]\n', '\n', '        if not self.hosts:\n', '            raise ValueError("Server can\'t run without any hosts!")\n', '\n', '        self.handler = GenericHandler({host.host: host.path_map for host in self.hosts})\n', '\n', '    @classmethod\n', '    def from_config(cls, cfg):\n', '        o = cls([], None, cfg.get("port", 1965))\n', '        o.load(cfg)\n', '        return o\n'], '/nix/store/3hj7jdn5dygvzz68wbrigldinh3xrd8s-amethyst-0.0.1/lib/python3.10/site-packages/amethyst/config.py'), '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/streams.py': (25762, 1.0, ['__all__ = (\n', "    'StreamReader', 'StreamWriter', 'StreamReaderProtocol',\n", "    'open_connection', 'start_server')\n", '\n', 'import collections\n', 'import socket\n', 'import sys\n', 'import warnings\n', 'import weakref\n', '\n', "if hasattr(socket, 'AF_UNIX'):\n", "    __all__ += ('open_unix_connection', 'start_unix_server')\n", '\n', 'from . import coroutines\n', 'from . import events\n', 'from . import exceptions\n', 'from . import format_helpers\n', 'from . import protocols\n', 'from .log import logger\n', 'from .tasks import sleep\n', '\n', '\n', '_DEFAULT_LIMIT = 2 ** 16  # 64 KiB\n', '\n', '\n', 'async def open_connection(host=None, port=None, *,\n', '                          limit=_DEFAULT_LIMIT, **kwds):\n', '    """A wrapper for create_connection() returning a (reader, writer) pair.\n', '\n', '    The reader returned is a StreamReader instance; the writer is a\n', '    StreamWriter instance.\n', '\n', '    The arguments are all the usual arguments to create_connection()\n', '    except protocol_factory; most common are positional host and port,\n', '    with various optional keyword arguments following.\n', '\n', '    Additional optional keyword arguments are loop (to set the event loop\n', '    instance to use) and limit (to set the buffer limit passed to the\n', '    StreamReader).\n', '\n', '    (If you want to customize the StreamReader and/or\n', "    StreamReaderProtocol classes, just copy the code -- there's\n", '    really nothing special here except some convenience.)\n', '    """\n', '    loop = events.get_running_loop()\n', '    reader = StreamReader(limit=limit, loop=loop)\n', '    protocol = StreamReaderProtocol(reader, loop=loop)\n', '    transport, _ = await loop.create_connection(\n', '        lambda: protocol, host, port, **kwds)\n', '    writer = StreamWriter(transport, protocol, reader, loop)\n', '    return reader, writer\n', '\n', '\n', 'async def start_server(client_connected_cb, host=None, port=None, *,\n', '                       limit=_DEFAULT_LIMIT, **kwds):\n', '    """Start a socket server, call back for each client connected.\n', '\n', '    The first parameter, `client_connected_cb`, takes two parameters:\n', '    client_reader, client_writer.  client_reader is a StreamReader\n', '    object, while client_writer is a StreamWriter object.  This\n', '    parameter can either be a plain callback function or a coroutine;\n', '    if it is a coroutine, it will be automatically converted into a\n', '    Task.\n', '\n', '    The rest of the arguments are all the usual arguments to\n', '    loop.create_server() except protocol_factory; most common are\n', '    positional host and port, with various optional keyword arguments\n', '    following.  The return value is the same as loop.create_server().\n', '\n', '    Additional optional keyword arguments are loop (to set the event loop\n', '    instance to use) and limit (to set the buffer limit passed to the\n', '    StreamReader).\n', '\n', '    The return value is the same as loop.create_server(), i.e. a\n', '    Server object which can be used to stop the service.\n', '    """\n', '    loop = events.get_running_loop()\n', '\n', '    def factory():\n', '        reader = StreamReader(limit=limit, loop=loop)\n', '        protocol = StreamReaderProtocol(reader, client_connected_cb,\n', '                                        loop=loop)\n', '        return protocol\n', '\n', '    return await loop.create_server(factory, host, port, **kwds)\n', '\n', '\n', "if hasattr(socket, 'AF_UNIX'):\n", '    # UNIX Domain Sockets are supported on this platform\n', '\n', '    async def open_unix_connection(path=None, *,\n', '                                   limit=_DEFAULT_LIMIT, **kwds):\n', '        """Similar to `open_connection` but works with UNIX Domain Sockets."""\n', '        loop = events.get_running_loop()\n', '\n', '        reader = StreamReader(limit=limit, loop=loop)\n', '        protocol = StreamReaderProtocol(reader, loop=loop)\n', '        transport, _ = await loop.create_unix_connection(\n', '            lambda: protocol, path, **kwds)\n', '        writer = StreamWriter(transport, protocol, reader, loop)\n', '        return reader, writer\n', '\n', '    async def start_unix_server(client_connected_cb, path=None, *,\n', '                                limit=_DEFAULT_LIMIT, **kwds):\n', '        """Similar to `start_server` but works with UNIX Domain Sockets."""\n', '        loop = events.get_running_loop()\n', '\n', '        def factory():\n', '            reader = StreamReader(limit=limit, loop=loop)\n', '            protocol = StreamReaderProtocol(reader, client_connected_cb,\n', '                                            loop=loop)\n', '            return protocol\n', '\n', '        return await loop.create_unix_server(factory, path, **kwds)\n', '\n', '\n', 'class FlowControlMixin(protocols.Protocol):\n', '    """Reusable flow control logic for StreamWriter.drain().\n', '\n', '    This implements the protocol methods pause_writing(),\n', '    resume_writing() and connection_lost().  If the subclass overrides\n', '    these it must call the super methods.\n', '\n', '    StreamWriter.drain() must wait for _drain_helper() coroutine.\n', '    """\n', '\n', '    def __init__(self, loop=None):\n', '        if loop is None:\n', '            self._loop = events._get_event_loop(stacklevel=4)\n', '        else:\n', '            self._loop = loop\n', '        self._paused = False\n', '        self._drain_waiters = collections.deque()\n', '        self._connection_lost = False\n', '\n', '    def pause_writing(self):\n', '        assert not self._paused\n', '        self._paused = True\n', '        if self._loop.get_debug():\n', '            logger.debug("%r pauses writing", self)\n', '\n', '    def resume_writing(self):\n', '        assert self._paused\n', '        self._paused = False\n', '        if self._loop.get_debug():\n', '            logger.debug("%r resumes writing", self)\n', '\n', '        for waiter in self._drain_waiters:\n', '            if not waiter.done():\n', '                waiter.set_result(None)\n', '\n', '    def connection_lost(self, exc):\n', '        self._connection_lost = True\n', '        # Wake up the writer(s) if currently paused.\n', '        if not self._paused:\n', '            return\n', '\n', '        for waiter in self._drain_waiters:\n', '            if not waiter.done():\n', '                if exc is None:\n', '                    waiter.set_result(None)\n', '                else:\n', '                    waiter.set_exception(exc)\n', '\n', '    async def _drain_helper(self):\n', '        if self._connection_lost:\n', "            raise ConnectionResetError('Connection lost')\n", '        if not self._paused:\n', '            return\n', '        waiter = self._loop.create_future()\n', '        self._drain_waiters.append(waiter)\n', '        try:\n', '            await waiter\n', '        finally:\n', '            self._drain_waiters.remove(waiter)\n', '\n', '    def _get_close_waiter(self, stream):\n', '        raise NotImplementedError\n', '\n', '\n', 'class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):\n', '    """Helper class to adapt between Protocol and StreamReader.\n', '\n', '    (This is a helper class instead of making StreamReader itself a\n', '    Protocol subclass, because the StreamReader has other potential\n', '    uses, and to prevent the user of the StreamReader to accidentally\n', '    call inappropriate methods of the protocol.)\n', '    """\n', '\n', '    _source_traceback = None\n', '\n', '    def __init__(self, stream_reader, client_connected_cb=None, loop=None):\n', '        super().__init__(loop=loop)\n', '        if stream_reader is not None:\n', '            self._stream_reader_wr = weakref.ref(stream_reader)\n', '            self._source_traceback = stream_reader._source_traceback\n', '        else:\n', '            self._stream_reader_wr = None\n', '        if client_connected_cb is not None:\n', '            # This is a stream created by the `create_server()` function.\n', '            # Keep a strong reference to the reader until a connection\n', '            # is established.\n', '            self._strong_reader = stream_reader\n', '        self._reject_connection = False\n', '        self._stream_writer = None\n', '        self._task = None\n', '        self._transport = None\n', '        self._client_connected_cb = client_connected_cb\n', '        self._over_ssl = False\n', '        self._closed = self._loop.create_future()\n', '\n', '    @property\n', '    def _stream_reader(self):\n', '        if self._stream_reader_wr is None:\n', '            return None\n', '        return self._stream_reader_wr()\n', '\n', '    def connection_made(self, transport):\n', '        if self._reject_connection:\n', '            context = {\n', "                'message': ('An open stream was garbage collected prior to '\n", "                            'establishing network connection; '\n", '                            \'call "stream.close()" explicitly.\')\n', '            }\n', '            if self._source_traceback:\n', "                context['source_traceback'] = self._source_traceback\n", '            self._loop.call_exception_handler(context)\n', '            transport.abort()\n', '            return\n', '        self._transport = transport\n', '        reader = self._stream_reader\n', '        if reader is not None:\n', '            reader.set_transport(transport)\n', "        self._over_ssl = transport.get_extra_info('sslcontext') is not None\n", '        if self._client_connected_cb is not None:\n', '            self._stream_writer = StreamWriter(transport, self,\n', '                                               reader,\n', '                                               self._loop)\n', '            res = self._client_connected_cb(reader,\n', '                                            self._stream_writer)\n', '            if coroutines.iscoroutine(res):\n', '                self._task = self._loop.create_task(res)\n', '            self._strong_reader = None\n', '\n', '    def connection_lost(self, exc):\n', '        reader = self._stream_reader\n', '        if reader is not None:\n', '            if exc is None:\n', '                reader.feed_eof()\n', '            else:\n', '                reader.set_exception(exc)\n', '        if not self._closed.done():\n', '            if exc is None:\n', '                self._closed.set_result(None)\n', '            else:\n', '                self._closed.set_exception(exc)\n', '        super().connection_lost(exc)\n', '        self._stream_reader_wr = None\n', '        self._stream_writer = None\n', '        self._task = None\n', '        self._transport = None\n', '\n', '    def data_received(self, data):\n', '        reader = self._stream_reader\n', '        if reader is not None:\n', '            reader.feed_data(data)\n', '\n', '    def eof_received(self):\n', '        reader = self._stream_reader\n', '        if reader is not None:\n', '            reader.feed_eof()\n', '        if self._over_ssl:\n', '            # Prevent a warning in SSLProtocol.eof_received:\n', '            # "returning true from eof_received()\n', '            # has no effect when using ssl"\n', '            return False\n', '        return True\n', '\n', '    def _get_close_waiter(self, stream):\n', '        return self._closed\n', '\n', '    def __del__(self):\n', '        # Prevent reports about unhandled exceptions.\n', '        # Better than self._closed._log_traceback = False hack\n', '        try:\n', '            closed = self._closed\n', '        except AttributeError:\n', '            pass  # failed constructor\n', '        else:\n', '            if closed.done() and not closed.cancelled():\n', '                closed.exception()\n', '\n', '\n', 'class StreamWriter:\n', '    """Wraps a Transport.\n', '\n', '    This exposes write(), writelines(), [can_]write_eof(),\n', '    get_extra_info() and close().  It adds drain() which returns an\n', '    optional Future on which you can wait for flow control.  It also\n', '    adds a transport property which references the Transport\n', '    directly.\n', '    """\n', '\n', '    def __init__(self, transport, protocol, reader, loop):\n', '        self._transport = transport\n', '        self._protocol = protocol\n', '        # drain() expects that the reader has an exception() method\n', '        assert reader is None or isinstance(reader, StreamReader)\n', '        self._reader = reader\n', '        self._loop = loop\n', '        self._complete_fut = self._loop.create_future()\n', '        self._complete_fut.set_result(None)\n', '\n', '    def __repr__(self):\n', "        info = [self.__class__.__name__, f'transport={self._transport!r}']\n", '        if self._reader is not None:\n', "            info.append(f'reader={self._reader!r}')\n", "        return '<{}>'.format(' '.join(info))\n", '\n', '    @property\n', '    def transport(self):\n', '        return self._transport\n', '\n', '    def write(self, data):\n', '        self._transport.write(data)\n', '\n', '    def writelines(self, data):\n', '        self._transport.writelines(data)\n', '\n', '    def write_eof(self):\n', '        return self._transport.write_eof()\n', '\n', '    def can_write_eof(self):\n', '        return self._transport.can_write_eof()\n', '\n', '    def close(self):\n', '        return self._transport.close()\n', '\n', '    def is_closing(self):\n', '        return self._transport.is_closing()\n', '\n', '    async def wait_closed(self):\n', '        await self._protocol._get_close_waiter(self)\n', '\n', '    def get_extra_info(self, name, default=None):\n', '        return self._transport.get_extra_info(name, default)\n', '\n', '    async def drain(self):\n', '        """Flush the write buffer.\n', '\n', '        The intended use is to write\n', '\n', '          w.write(data)\n', '          await w.drain()\n', '        """\n', '        if self._reader is not None:\n', '            exc = self._reader.exception()\n', '            if exc is not None:\n', '                raise exc\n', '        if self._transport.is_closing():\n', '            # Wait for protocol.connection_lost() call\n', '            # Raise connection closing error if any,\n', '            # ConnectionResetError otherwise\n', '            # Yield to the event loop so connection_lost() may be\n', '            # called.  Without this, _drain_helper() would return\n', '            # immediately, and code that calls\n', '            #     write(...); await drain()\n', '            # in a loop would never call connection_lost(), so it\n', '            # would not see an error when the socket is closed.\n', '            await sleep(0)\n', '        await self._protocol._drain_helper()\n', '\n', '\n', 'class StreamReader:\n', '\n', '    _source_traceback = None\n', '\n', '    def __init__(self, limit=_DEFAULT_LIMIT, loop=None):\n', '        # The line length limit is  a security feature;\n', '        # it also doubles as half the buffer limit.\n', '\n', '        if limit <= 0:\n', "            raise ValueError('Limit cannot be <= 0')\n", '\n', '        self._limit = limit\n', '        if loop is None:\n', '            self._loop = events._get_event_loop()\n', '        else:\n', '            self._loop = loop\n', '        self._buffer = bytearray()\n', "        self._eof = False    # Whether we're done.\n", '        self._waiter = None  # A future used by _wait_for_data()\n', '        self._exception = None\n', '        self._transport = None\n', '        self._paused = False\n', '        if self._loop.get_debug():\n', '            self._source_traceback = format_helpers.extract_stack(\n', '                sys._getframe(1))\n', '\n', '    def __repr__(self):\n', "        info = ['StreamReader']\n", '        if self._buffer:\n', "            info.append(f'{len(self._buffer)} bytes')\n", '        if self._eof:\n', "            info.append('eof')\n", '        if self._limit != _DEFAULT_LIMIT:\n', "            info.append(f'limit={self._limit}')\n", '        if self._waiter:\n', "            info.append(f'waiter={self._waiter!r}')\n", '        if self._exception:\n', "            info.append(f'exception={self._exception!r}')\n", '        if self._transport:\n', "            info.append(f'transport={self._transport!r}')\n", '        if self._paused:\n', "            info.append('paused')\n", "        return '<{}>'.format(' '.join(info))\n", '\n', '    def exception(self):\n', '        return self._exception\n', '\n', '    def set_exception(self, exc):\n', '        self._exception = exc\n', '\n', '        waiter = self._waiter\n', '        if waiter is not None:\n', '            self._waiter = None\n', '            if not waiter.cancelled():\n', '                waiter.set_exception(exc)\n', '\n', '    def _wakeup_waiter(self):\n', '        """Wakeup read*() functions waiting for data or EOF."""\n', '        waiter = self._waiter\n', '        if waiter is not None:\n', '            self._waiter = None\n', '            if not waiter.cancelled():\n', '                waiter.set_result(None)\n', '\n', '    def set_transport(self, transport):\n', "        assert self._transport is None, 'Transport already set'\n", '        self._transport = transport\n', '\n', '    def _maybe_resume_transport(self):\n', '        if self._paused and len(self._buffer) <= self._limit:\n', '            self._paused = False\n', '            self._transport.resume_reading()\n', '\n', '    def feed_eof(self):\n', '        self._eof = True\n', '        self._wakeup_waiter()\n', '\n', '    def at_eof(self):\n', '        """Return True if the buffer is empty and \'feed_eof\' was called."""\n', '        return self._eof and not self._buffer\n', '\n', '    def feed_data(self, data):\n', "        assert not self._eof, 'feed_data after feed_eof'\n", '\n', '        if not data:\n', '            return\n', '\n', '        self._buffer.extend(data)\n', '        self._wakeup_waiter()\n', '\n', '        if (self._transport is not None and\n', '                not self._paused and\n', '                len(self._buffer) > 2 * self._limit):\n', '            try:\n', '                self._transport.pause_reading()\n', '            except NotImplementedError:\n', "                # The transport can't be paused.\n", "                # We'll just have to buffer all data.\n", "                # Forget the transport so we don't keep trying.\n", '                self._transport = None\n', '            else:\n', '                self._paused = True\n', '\n', '    async def _wait_for_data(self, func_name):\n', '        """Wait until feed_data() or feed_eof() is called.\n', '\n', '        If stream was paused, automatically resume it.\n', '        """\n', '        # StreamReader uses a future to link the protocol feed_data() method\n', '        # to a read coroutine. Running two read coroutines at the same time\n', '        # would have an unexpected behaviour. It would not possible to know\n', '        # which coroutine would get the next data.\n', '        if self._waiter is not None:\n', '            raise RuntimeError(\n', "                f'{func_name}() called while another coroutine is '\n", "                f'already waiting for incoming data')\n", '\n', "        assert not self._eof, '_wait_for_data after EOF'\n", '\n', '        # Waiting for data while paused will make deadlock, so prevent it.\n', '        # This is essential for readexactly(n) for case when n > self._limit.\n', '        if self._paused:\n', '            self._paused = False\n', '            self._transport.resume_reading()\n', '\n', '        self._waiter = self._loop.create_future()\n', '        try:\n', '            await self._waiter\n', '        finally:\n', '            self._waiter = None\n', '\n', '    async def readline(self):\n', '        """Read chunk of data from the stream until newline (b\'\\n\') is found.\n', '\n', '        On success, return chunk that ends with newline. If only partial\n', '        line can be read due to EOF, return incomplete line without\n', '        terminating newline. When EOF was reached while no bytes read, empty\n', '        bytes object is returned.\n', '\n', '        If limit is reached, ValueError will be raised. In that case, if\n', '        newline was found, complete line including newline will be removed\n', '        from internal buffer. Else, internal buffer will be cleared. Limit is\n', '        compared against part of the line without newline.\n', '\n', '        If stream was paused, this function will automatically resume it if\n', '        needed.\n', '        """\n', "        sep = b'\\n'\n", '        seplen = len(sep)\n', '        try:\n', '            line = await self.readuntil(sep)\n', '        except exceptions.IncompleteReadError as e:\n', '            return e.partial\n', '        except exceptions.LimitOverrunError as e:\n', '            if self._buffer.startswith(sep, e.consumed):\n', '                del self._buffer[:e.consumed + seplen]\n', '            else:\n', '                self._buffer.clear()\n', '            self._maybe_resume_transport()\n', '            raise ValueError(e.args[0])\n', '        return line\n', '\n', "    async def readuntil(self, separator=b'\\n'):\n", '        """Read data from the stream until ``separator`` is found.\n', '\n', '        On success, the data and separator will be removed from the\n', '        internal buffer (consumed). Returned data will include the\n', '        separator at the end.\n', '\n', '        Configured stream limit is used to check result. Limit sets the\n', '        maximal length of data that can be returned, not counting the\n', '        separator.\n', '\n', '        If an EOF occurs and the complete separator is still not found,\n', '        an IncompleteReadError exception will be raised, and the internal\n', '        buffer will be reset.  The IncompleteReadError.partial attribute\n', '        may contain the separator partially.\n', '\n', '        If the data cannot be read because of over limit, a\n', '        LimitOverrunError exception  will be raised, and the data\n', '        will be left in the internal buffer, so it can be read again.\n', '        """\n', '        seplen = len(separator)\n', '        if seplen == 0:\n', "            raise ValueError('Separator should be at least one-byte string')\n", '\n', '        if self._exception is not None:\n', '            raise self._exception\n', '\n', '        # Consume whole buffer except last bytes, which length is\n', "        # one less than seplen. Let's check corner cases with\n", "        # separator='SEPARATOR':\n", '        # * we have received almost complete separator (without last\n', "        #   byte). i.e buffer='some textSEPARATO'. In this case we\n", '        #   can safely consume len(separator) - 1 bytes.\n', '        # * last byte of buffer is first byte of separator, i.e.\n', "        #   buffer='abcdefghijklmnopqrS'. We may safely consume\n", '        #   everything except that last byte, but this require to\n', '        #   analyze bytes of buffer that match partial separator.\n', '        #   This is slow and/or require FSM. For this case our\n', '        #   implementation is not optimal, since require rescanning\n', '        #   of data that is known to not belong to separator. In\n', '        #   real world, separator will not be so long to notice\n', '        #   performance problems. Even when reading MIME-encoded\n', '        #   messages :)\n', '\n', '        # `offset` is the number of bytes from the beginning of the buffer\n', '        # where there is no occurrence of `separator`.\n', '        offset = 0\n', '\n', '        # Loop until we find `separator` in the buffer, exceed the buffer size,\n', '        # or an EOF has happened.\n', '        while True:\n', '            buflen = len(self._buffer)\n', '\n', '            # Check if we now have enough data in the buffer for `separator` to\n', '            # fit.\n', '            if buflen - offset >= seplen:\n', '                isep = self._buffer.find(separator, offset)\n', '\n', '                if isep != -1:\n', '                    # `separator` is in the buffer. `isep` will be used later\n', '                    # to retrieve the data.\n', '                    break\n', '\n', '                # see upper comment for explanation.\n', '                offset = buflen + 1 - seplen\n', '                if offset > self._limit:\n', '                    raise exceptions.LimitOverrunError(\n', "                        'Separator is not found, and chunk exceed the limit',\n", '                        offset)\n', '\n', '            # Complete message (with full separator) may be present in buffer\n', '            # even when EOF flag is set. This may happen when the last chunk\n', "            # adds data which makes separator be found. That's why we check for\n", '            # EOF *ater* inspecting the buffer.\n', '            if self._eof:\n', '                chunk = bytes(self._buffer)\n', '                self._buffer.clear()\n', '                raise exceptions.IncompleteReadError(chunk, None)\n', '\n', '            # _wait_for_data() will resume reading if stream was paused.\n', "            await self._wait_for_data('readuntil')\n", '\n', '        if isep > self._limit:\n', '            raise exceptions.LimitOverrunError(\n', "                'Separator is found, but chunk is longer than limit', isep)\n", '\n', '        chunk = self._buffer[:isep + seplen]\n', '        del self._buffer[:isep + seplen]\n', '        self._maybe_resume_transport()\n', '        return bytes(chunk)\n', '\n', '    async def read(self, n=-1):\n', '        """Read up to `n` bytes from the stream.\n', '\n', '        If n is not provided, or set to -1, read until EOF and return all read\n', '        bytes. If the EOF was received and the internal buffer is empty, return\n', '        an empty bytes object.\n', '\n', '        If n is zero, return empty bytes object immediately.\n', '\n', '        If n is positive, this function try to read `n` bytes, and may return\n', '        less or equal bytes than requested, but at least one byte. If EOF was\n', '        received before any byte is read, this function returns empty byte\n', '        object.\n', '\n', '        Returned value is not limited with limit, configured at stream\n', '        creation.\n', '\n', '        If stream was paused, this function will automatically resume it if\n', '        needed.\n', '        """\n', '\n', '        if self._exception is not None:\n', '            raise self._exception\n', '\n', '        if n == 0:\n', "            return b''\n", '\n', '        if n < 0:\n', '            # This used to just loop creating a new waiter hoping to\n', '            # collect everything in self._buffer, but that would\n', '            # deadlock if the subprocess sends more than self.limit\n', '            # bytes.  So just call self.read(self._limit) until EOF.\n', '            blocks = []\n', '            while True:\n', '                block = await self.read(self._limit)\n', '                if not block:\n', '                    break\n', '                blocks.append(block)\n', "            return b''.join(blocks)\n", '\n', '        if not self._buffer and not self._eof:\n', "            await self._wait_for_data('read')\n", '\n', '        # This will work right even if buffer is less than n bytes\n', '        data = bytes(self._buffer[:n])\n', '        del self._buffer[:n]\n', '\n', '        self._maybe_resume_transport()\n', '        return data\n', '\n', '    async def readexactly(self, n):\n', '        """Read exactly `n` bytes.\n', '\n', '        Raise an IncompleteReadError if EOF is reached before `n` bytes can be\n', '        read. The IncompleteReadError.partial attribute of the exception will\n', '        contain the partial read bytes.\n', '\n', '        if n is zero, return empty bytes object.\n', '\n', '        Returned value is not limited with limit, configured at stream\n', '        creation.\n', '\n', '        If stream was paused, this function will automatically resume it if\n', '        needed.\n', '        """\n', '        if n < 0:\n', "            raise ValueError('readexactly size can not be less than zero')\n", '\n', '        if self._exception is not None:\n', '            raise self._exception\n', '\n', '        if n == 0:\n', "            return b''\n", '\n', '        while len(self._buffer) < n:\n', '            if self._eof:\n', '                incomplete = bytes(self._buffer)\n', '                self._buffer.clear()\n', '                raise exceptions.IncompleteReadError(incomplete, n)\n', '\n', "            await self._wait_for_data('readexactly')\n", '\n', '        if len(self._buffer) == n:\n', '            data = bytes(self._buffer)\n', '            self._buffer.clear()\n', '        else:\n', '            data = bytes(self._buffer[:n])\n', '            del self._buffer[:n]\n', '        self._maybe_resume_transport()\n', '        return data\n', '\n', '    def __aiter__(self):\n', '        return self\n', '\n', '    async def __anext__(self):\n', '        val = await self.readline()\n', "        if val == b'':\n", '            raise StopAsyncIteration\n', '        return val\n'], '/nix/store/lbn7f0d2k36i4bgfdrjdwj7npy3r3h5d-python3-3.10.8/lib/python3.10/asyncio/streams.py')}

Modules

functools

os

sys

tokenize