STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
capture.py
Go to the documentation of this file.
1
"""Capture what one thread prints, without touching any other thread's output.
2
3
``contextlib.redirect_stdout`` swaps ``sys.stdout`` for the whole process. In the API, burns run on
4
daemon threads two at a time: two overlapping flights restored each other's buffers, and the
5
server went on printing into a StringIO for ever while other requests' prints landed in a run's
6
notes. Here ``sys.stdout`` is replaced once by a router that sends a thread's writes to that
7
thread's buffer while it is capturing, and everything else to the real stream.
8
"""
9
10
from
__future__
import
annotations
11
12
import
contextlib
13
import
io
14
import
sys
15
import
threading
16
from
typing
import
Iterator
17
18
_local = threading.local()
19
_install_lock = threading.Lock()
20
21
22
class
_ThreadRouter
(io.TextIOBase):
23
def
__init__
(self, real: object) ->
None
:
24
self.
real
= real
25
26
def
_target
(self) -> object:
27
return
getattr(_local,
"buffer"
,
None
)
or
self.
real
28
29
def
write
(self, s: str) -> int:
# type: ignore[override]
30
return
self.
_target
().
write
(s)
# type: ignore[attr-defined]
31
32
def
flush
(self) -> None:
33
target = self.
_target
()
34
if
hasattr(target,
"flush"
):
35
target.flush()
# type: ignore[attr-defined]
36
37
def
isatty
(self) -> bool:
38
return
bool(getattr(self.
real
,
"isatty"
,
lambda
:
False
)())
39
40
@property
41
def
encoding
(self) -> str:
# type: ignore[override]
42
return
getattr(self.
real
,
"encoding"
,
"utf-8"
)
43
44
45
def
_install
() -> None:
46
with
_install_lock:
47
if
not
isinstance(sys.stdout, _ThreadRouter):
48
sys.stdout =
_ThreadRouter
(sys.stdout)
49
50
51
@contextlib.contextmanager
52
def
thread_stdout
() -> Iterator[io.StringIO]:
53
"""Everything this thread prints inside the block, and nothing any other thread prints."""
54
_install
()
55
previous = getattr(_local,
"buffer"
,
None
)
56
buffer = io.StringIO()
57
_local.buffer = buffer
58
try
:
59
yield
buffer
60
finally
:
61
_local.buffer = previous
engine.layerx.capture._ThreadRouter
Definition
capture.py:22
engine.layerx.capture._ThreadRouter._target
object _target(self)
Definition
capture.py:26
engine.layerx.capture._ThreadRouter.encoding
str encoding(self)
Definition
capture.py:41
engine.layerx.capture._ThreadRouter.isatty
bool isatty(self)
Definition
capture.py:37
engine.layerx.capture._ThreadRouter.__init__
None __init__(self, object real)
Definition
capture.py:23
engine.layerx.capture._ThreadRouter.write
int write(self, str s)
Definition
capture.py:29
engine.layerx.capture._ThreadRouter.real
real
Definition
capture.py:24
engine.layerx.capture._ThreadRouter.flush
None flush(self)
Definition
capture.py:32
engine.layerx.capture.thread_stdout
Iterator[io.StringIO] thread_stdout()
Definition
capture.py:52
engine.layerx.capture._install
None _install()
Definition
capture.py:45
EngineDesign
engine
layerx
capture.py
Generated by
1.15.0