31 items
NAME ↑ SIZE MODIFIED PERMS ACTIONS
.. / Parent Directory
__pycache__ — dir
2026-06-03 15:44 · rwxr-xr-x
2026-06-03 15:44 rwxr-xr-x
__init__.py — 1.25 KB
2025-10-31 18:40 · rw-r--r--
1.25 KB 2025-10-31 18:40 rw-r--r--
__main__.py — 3.3 KB
2025-10-31 18:40 · rw-r--r--
3.3 KB 2025-10-31 18:40 rw-r--r--
base_events.py — 72.45 KB
2025-10-31 18:40 · rw-r--r--
72.45 KB 2025-10-31 18:40 rw-r--r--
base_futures.py — 2.51 KB
2025-10-31 18:40 · rw-r--r--
2.51 KB 2025-10-31 18:40 rw-r--r--
base_subprocess.py — 8.64 KB
2025-10-31 18:40 · rw-r--r--
8.64 KB 2025-10-31 18:40 rw-r--r--
base_tasks.py — 2.41 KB
2025-10-31 18:40 · rw-r--r--
2.41 KB 2025-10-31 18:40 rw-r--r--
constants.py — 888 B
2025-10-31 18:40 · rw-r--r--
888 B 2025-10-31 18:40 rw-r--r--
coroutines.py — 8.59 KB
2025-10-31 18:40 · rw-r--r--
8.59 KB 2025-10-31 18:40 rw-r--r--
events.py — 25.83 KB
2025-10-31 18:40 · rw-r--r--
25.83 KB 2025-10-31 18:40 rw-r--r--
exceptions.py — 1.59 KB
2025-10-31 18:40 · rw-r--r--
1.59 KB 2025-10-31 18:40 rw-r--r--
format_helpers.py — 2.35 KB
2025-10-31 18:40 · rw-r--r--
2.35 KB 2025-10-31 18:40 rw-r--r--
futures.py — 13.71 KB
2025-10-31 18:40 · rw-r--r--
13.71 KB 2025-10-31 18:40 rw-r--r--
locks.py — 14.83 KB
2025-10-31 18:40 · rw-r--r--
14.83 KB 2025-10-31 18:40 rw-r--r--
log.py — 124 B
2025-10-31 18:40 · rw-r--r--
124 B 2025-10-31 18:40 rw-r--r--
proactor_events.py — 31.39 KB
2025-10-31 18:40 · rw-r--r--
31.39 KB 2025-10-31 18:40 rw-r--r--
protocols.py — 6.79 KB
2025-10-31 18:40 · rw-r--r--
6.79 KB 2025-10-31 18:40 rw-r--r--
queues.py — 8.11 KB
2025-10-31 18:40 · rw-r--r--
8.11 KB 2025-10-31 18:40 rw-r--r--
runners.py — 2.08 KB
2025-10-31 18:40 · rw-r--r--
2.08 KB 2025-10-31 18:40 rw-r--r--
selector_events.py — 38.57 KB
2025-10-31 18:40 · rw-r--r--
38.57 KB 2025-10-31 18:40 rw-r--r--
sslproto.py — 26.82 KB
2025-10-31 18:40 · rw-r--r--
26.82 KB 2025-10-31 18:40 rw-r--r--
staggered.py — 5.85 KB
2025-10-31 18:40 · rw-r--r--
5.85 KB 2025-10-31 18:40 rw-r--r--
streams.py — 26.03 KB
2025-10-31 18:40 · rw-r--r--
26.03 KB 2025-10-31 18:40 rw-r--r--
subprocess.py — 7.88 KB
2025-10-31 18:40 · rw-r--r--
7.88 KB 2025-10-31 18:40 rw-r--r--
tasks.py — 33.61 KB
2025-10-31 18:40 · rw-r--r--
33.61 KB 2025-10-31 18:40 rw-r--r--
threads.py — 790 B
2025-10-31 18:40 · rw-r--r--
790 B 2025-10-31 18:40 rw-r--r--
transports.py — 10.47 KB
2025-10-31 18:40 · rw-r--r--
10.47 KB 2025-10-31 18:40 rw-r--r--
trsock.py — 5.74 KB
2025-10-31 18:40 · rw-r--r--
5.74 KB 2025-10-31 18:40 rw-r--r--
unix_events.py — 50.54 KB
2025-10-31 18:40 · rw-r--r--
50.54 KB 2025-10-31 18:40 rw-r--r--
windows_events.py — 32.28 KB
2025-10-31 18:40 · rw-r--r--
32.28 KB 2025-10-31 18:40 rw-r--r--
windows_utils.py — 4.94 KB
2025-10-31 18:40 · rw-r--r--
4.94 KB 2025-10-31 18:40 rw-r--r--
ONLINE
asyncio
31 items
05:43:27
TERMINAL FM
Edit
Preview
Download
Rename
Copy
Chmod
Delete
import collections import subprocess import warnings from . import protocols from . import transports from .log import logger class BaseSubprocessTransport(transports.SubprocessTransport): def __init__(self, loop, protocol, args, shell, stdin, stdout, stderr, bufsize, waiter=None, extra=None, **kwargs): super().__init__(extra) self._closed = False self._protocol = protocol self._loop = loop self._proc = None self._pid = None self._returncode = None self._exit_waiters = [] self._pending_calls = collections.deque() self._pipes = {} self._finished = False if stdin == subprocess.PIPE: self._pipes[0] = None if stdout == subprocess.PIPE: self._pipes[1] = None if stderr == subprocess.PIPE: self._pipes[2] = None # Create the child process: set the _proc attribute try: self._start(args=args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, bufsize=bufsize, **kwargs) except: self.close() raise self._pid = self._proc.pid self._extra['subprocess'] = self._proc if self._loop.get_debug(): if isinstance(args, (bytes, str)): program = args else: program = args[0] logger.debug('process %r created: pid %s', program, self._pid) self._loop.create_task(self._connect_pipes(waiter)) def __repr__(self): info = [self.__class__.__name__] if self._closed: info.append('closed') if self._pid is not None: info.append(f'pid={self._pid}') if self._returncode is not None: info.append(f'returncode={self._returncode}') elif self._pid is not None: info.append('running') else: info.append('not started') stdin = self._pipes.get(0) if stdin is not None: info.append(f'stdin={stdin.pipe}') stdout = self._pipes.get(1) stderr = self._pipes.get(2) if stdout is not None and stderr is stdout: info.append(f'stdout=stderr={stdout.pipe}') else: if stdout is not None: info.append(f'stdout={stdout.pipe}') if stderr is not None: info.append(f'stderr={stderr.pipe}') return '<{}>'.format(' '.join(info)) def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError def set_protocol(self, protocol): self._protocol = protocol def get_protocol(self): return self._protocol def is_closing(self): return self._closed def close(self): if self._closed: return self._closed = True for proto in self._pipes.values(): if proto is None: continue proto.pipe.close() if (self._proc is not None and # has the child process finished? self._returncode is None and # the child process has finished, but the # transport hasn't been notified yet? self._proc.poll() is None): if self._loop.get_debug(): logger.warning('Close running child process: kill %r', self) try: self._proc.kill() except ProcessLookupError: pass # Don't clear the _proc reference yet: _post_init() may still run def __del__(self, _warn=warnings.warn): if not self._closed: _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) self.close() def get_pid(self): return self._pid def get_returncode(self): return self._returncode def get_pipe_transport(self, fd): if fd in self._pipes: return self._pipes[fd].pipe else: return None def _check_proc(self): if self._proc is None: raise ProcessLookupError() def send_signal(self, signal): self._check_proc() self._proc.send_signal(signal) def terminate(self): self._check_proc() self._proc.terminate() def kill(self): self._check_proc() self._proc.kill() async def _connect_pipes(self, waiter): try: proc = self._proc loop = self._loop if proc.stdin is not None: _, pipe = await loop.connect_write_pipe( lambda: WriteSubprocessPipeProto(self, 0), proc.stdin) self._pipes[0] = pipe if proc.stdout is not None: _, pipe = await loop.connect_read_pipe( lambda: ReadSubprocessPipeProto(self, 1), proc.stdout) self._pipes[1] = pipe if proc.stderr is not None: _, pipe = await loop.connect_read_pipe( lambda: ReadSubprocessPipeProto(self, 2), proc.stderr) self._pipes[2] = pipe assert self._pending_calls is not None loop.call_soon(self._protocol.connection_made, self) for callback, data in self._pending_calls: loop.call_soon(callback, *data) self._pending_calls = None except (SystemExit, KeyboardInterrupt): raise except BaseException as exc: if waiter is not None and not waiter.cancelled(): waiter.set_exception(exc) else: if waiter is not None and not waiter.cancelled(): waiter.set_result(None) def _call(self, cb, *data): if self._pending_calls is not None: self._pending_calls.append((cb, data)) else: self._loop.call_soon(cb, *data) def _pipe_connection_lost(self, fd, exc): self._call(self._protocol.pipe_connection_lost, fd, exc) self._try_finish() def _pipe_data_received(self, fd, data): self._call(self._protocol.pipe_data_received, fd, data) def _process_exited(self, returncode): assert returncode is not None, returncode assert self._returncode is None, self._returncode if self._loop.get_debug(): logger.info('%r exited with return code %r', self, returncode) self._returncode = returncode if self._proc.returncode is None: # asyncio uses a child watcher: copy the status into the Popen # object. On Python 3.6, it is required to avoid a ResourceWarning. self._proc.returncode = returncode self._call(self._protocol.process_exited) self._try_finish() # wake up futures waiting for wait() for waiter in self._exit_waiters: if not waiter.cancelled(): waiter.set_result(returncode) self._exit_waiters = None async def _wait(self): """Wait until the process exit and return the process return code. This method is a coroutine.""" if self._returncode is not None: return self._returncode waiter = self._loop.create_future() self._exit_waiters.append(waiter) return await waiter def _try_finish(self): assert not self._finished if self._returncode is None: return if all(p is not None and p.disconnected for p in self._pipes.values()): self._finished = True self._call(self._call_connection_lost, None) def _call_connection_lost(self, exc): try: self._protocol.connection_lost(exc) finally: self._loop = None self._proc = None self._protocol = None class WriteSubprocessPipeProto(protocols.BaseProtocol): def __init__(self, proc, fd): self.proc = proc self.fd = fd self.pipe = None self.disconnected = False def connection_made(self, transport): self.pipe = transport def __repr__(self): return f'<{self.__class__.__name__} fd={self.fd} pipe={self.pipe!r}>' def connection_lost(self, exc): self.disconnected = True self.proc._pipe_connection_lost(self.fd, exc) self.proc = None def pause_writing(self): self.proc._protocol.pause_writing() def resume_writing(self): self.proc._protocol.resume_writing() class ReadSubprocessPipeProto(WriteSubprocessPipeProto, protocols.Protocol): def data_received(self, data): self.proc._pipe_data_received(self.fd, data)