Files
emod-cli/debug_mod/DEBUG_ENV_SCRIPT/Lifecycle.py

99 lines
2.6 KiB
Python
Raw Normal View History

# -*- 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