💾 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
⬅️ Previous capture (2022-07-16)
-=-=-=-=-=-=-
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.
checkcache(filename=None) Discard cache entries that are out of date. (This is not checked upon each call!)
clearcache() Clear the cache entirely.
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(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(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(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.
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('(