# -*- coding: utf-8 -*- import sys import threading _OUTPUT_PREFIX = "[Python] " _ACTIVE_SYSTEMS = set() _STATE_LOCK = threading.Lock() _ORIGINAL_STDOUT = None _ORIGINAL_STDERR = None class OutputWrapper(object): _emod_cli_debug_wrapper = True def __init__(self, stream): self.stream = stream self.lock = threading.Lock() self.buffer = [] def __getattr__(self, name): return getattr(self.stream, name) def write(self, data): with self.lock: parts = data.splitlines(True) for part in parts: if part.endswith("\n"): if self.buffer: line = "".join(self.buffer) + part self.buffer = [] else: line = part self.stream.write(_OUTPUT_PREFIX + line) else: self.buffer.append(part) def close(self): self.flush() return self.stream.close() def flush(self): with self.lock: if self.buffer: self.stream.write(_OUTPUT_PREFIX + "".join(self.buffer)) self.buffer = [] self.stream.flush() def writelines(self, lines): for line in lines: self.write(line) def fileno(self): return self.stream.fileno() def _install_output_wrapper_locked(): global _ORIGINAL_STDOUT, _ORIGINAL_STDERR if not getattr(sys.stdout, "_emod_cli_debug_wrapper", False): _ORIGINAL_STDOUT = sys.stdout sys.stdout = OutputWrapper(sys.stdout) elif _ORIGINAL_STDOUT is None: _ORIGINAL_STDOUT = getattr(sys.stdout, "stream") if not getattr(sys.stderr, "_emod_cli_debug_wrapper", False): _ORIGINAL_STDERR = sys.stderr sys.stderr = OutputWrapper(sys.stderr) elif _ORIGINAL_STDERR is None: _ORIGINAL_STDERR = getattr(sys.stderr, "stream") def install_output_wrapper(): with _STATE_LOCK: _install_output_wrapper_locked() def activate(system): with _STATE_LOCK: _install_output_wrapper_locked() _ACTIVE_SYSTEMS.add(system) def deactivate(system): global _ORIGINAL_STDOUT, _ORIGINAL_STDERR with _STATE_LOCK: _ACTIVE_SYSTEMS.discard(system) if _ACTIVE_SYSTEMS: return if _ORIGINAL_STDOUT is None or _ORIGINAL_STDERR is None: return sys.stdout.flush() sys.stderr.flush() sys.stdout = _ORIGINAL_STDOUT sys.stderr = _ORIGINAL_STDERR _ORIGINAL_STDOUT = None _ORIGINAL_STDERR = None