from subprocess import PIPE, STDOUT, Popen from importlib import import_module from threading import Thread from typing import Callable from pathlib import Path from re import compile import data def reader() -> None: if data.proc.stdout: for line in data.proc.stdout: line = line.rstrip("\n") print(line) for pattern, func in data.output_binds: match = pattern.match(line) if match: func(*match.groups()) break def onConsoleOutput(pattern: str) -> Callable: def decorator(func: Callable) -> Callable: data.output_binds.append((compile(pattern), func)) return func return decorator def sendCommand(cmd: str) -> None: if data.proc.stdin: data.proc.stdin.write(cmd+"\n") data.proc.stdin.flush() if __name__ == "__main__": data.initializeProc("python -u program.py") for file in Path("modules").iterdir(): if file.name.endswith(".py"): import_module("modules."+file.name[:-3]) t = Thread(target=reader, daemon=True) t.start() try: while data.proc.poll() is None: sendCommand(input()) except KeyboardInterrupt: sendCommand("stop") data.proc.wait()