6 from contextlib
import contextmanager, nested
7 from threading
import Thread
9 from tempfile
import mkdtemp
10 from os.path
import join
as pjoin
11 from os
import (dup, fdopen, open
as osopen, O_NONBLOCK, O_RDONLY, remove,
13 from fcntl
import fcntl, F_GETFL, F_SETFL
14 from select
import select
15 from sys
import stdout, stderr
17 from ctypes
import PyDLL, CDLL, c_void_p, c_char_p, py_object
29 PyFile_AsFile =
make_fn(pyapi.PyFile_AsFile, FILE_p, py_object)
30 freopen =
make_fn(this_exe.freopen, FILE_p, c_char_p, c_char_p, FILE_p)
35 Create a fifo in a temporary place.
38 filename = pjoin(tmpdir,
'myfifo')
42 print(
"Failed to create FIFO: %s" % e, file=stderr)
55 flags = fcntl(fd, F_GETFL)
56 if flags & O_NONBLOCK:
58 fcntl(fd, F_SETFL, flags)
62 Sit there, reading lines from the pipe `filename`, sending those for which
63 `filter_()` returns False to `real_stdout`
65 with fdopen(osopen(filename, O_NONBLOCK | O_RDONLY))
as fd:
67 rlist, _, _ =
select([fd], [], [])
74 filt_content.write(line)
76 real_stdout.write(line)
81 Operate a read_thread_func in another thread. Block with statement exit
82 until the function completes.
84 reader_thread = Thread(target=reader_thread_func, args=args)
92 def silence(filter_=lambda line:
True, file_=stdout):
94 Prevent lines matching `filter_` ending up on `file_` (defaults to stdout)
102 if not isinstance(file_, file):
107 saved_stdout = dup(file_.fileno())
110 from io
import StringIO
111 filt_content = StringIO()
113 with nested(fdopen(saved_stdout,
"w"),
fifo())
as (real_stdout, filename):
116 real_stdout, filt_content)
119 freopen(filename,
"w", stdout_file)
124 freopen(
"/dev/fd/%i" % saved_stdout,
"w", stdout_file)
127 print(
"Hit an exception. Filtered content:")
128 print(filt_content.getvalue())
133 from sys
import stdout, stderr
134 with nested(
silence(filter_, stdout),
silence(filter_, stderr))
as (so, se):
139 def filter_hello(line):
140 if line.startswith(
"Data source lookup using"):
143 print(
"Before with block..")
146 from DQUtils.db
import Databases
147 f = Databases.get_folder(
"DQMFONL")
148 print(
"Sensible stuff!")
152 print(
"I am after the silence block")
156 print(
"Before silence.")
158 with silence()
as filt_content:
160 raise RuntimeError(
"Error.")
163 print(
"After silence")
164 print(
"Stuff?", len(filt_content.getvalue()))
166 if __name__ ==
"__main__":