Skip to content

Commit 051af87

Browse files
authored
Redirect io (#69)
1 parent 97e06f3 commit 051af87

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

baseclasses/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "1.5.4"
1+
__version__ = "1.6.0"
22

33
from .problems import (
44
AeroProblem,

baseclasses/utils/redirectIO.py

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from contextlib import contextmanager
2+
import io
3+
import os
4+
import sys
5+
6+
"""
7+
Functions for redirecting stdout/stderr to different streams
8+
9+
Based on: http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/.
10+
"""
11+
12+
13+
def redirectIO(f_out, f_err=None):
14+
"""
15+
This function redirects stdout/stderr to the given file handle.
16+
17+
Parameters
18+
----------
19+
f_out : file
20+
A file stream to redirect stdout to
21+
22+
f_err : file
23+
A file stream to redirect stderr to. If none is specified it is set to `f_out`
24+
"""
25+
26+
if f_err is None:
27+
f_err = f_out
28+
29+
orig_out = sys.stdout.fileno()
30+
orig_err = sys.stderr.fileno()
31+
32+
# flush the standard out
33+
sys.stdout.flush()
34+
sys.stderr.flush()
35+
36+
# close the standard
37+
sys.stdout.close()
38+
sys.stderr.close()
39+
40+
os.dup2(f_out.fileno(), orig_out)
41+
os.dup2(f_err.fileno(), orig_err)
42+
43+
# reopen the stream with new file descriptors
44+
sys.stdout = io.TextIOWrapper(os.fdopen(orig_out, "wb"))
45+
sys.stderr = io.TextIOWrapper(os.fdopen(orig_err, "wb"))
46+
47+
48+
@contextmanager
49+
def redirectingIO(f_out, f_err=None):
50+
"""
51+
A function that redirects stdout in a with block and returns to the stdout after the `with` block completes.
52+
The filestream passed to this function will be closed after exiting the `with` block.
53+
54+
Here is an example of usage where all adflow output is redirected to the file `adflow_out.txt`:
55+
>>> from baseclasses.utils import redirectIO
56+
>>> print("Printing some information to terminal")
57+
>>> with redirectIO.redirectingIO(open("adflow_out.txt", "w")):
58+
... CFDSolver = ADFLOW(options=options)
59+
... CFDSolver(AeroProblem(**apOptions)
60+
>>> print("Printing some more information to terminal")
61+
62+
Parameters
63+
----------
64+
f_out : file
65+
A file stream that stdout should be redirected to
66+
67+
f_err : file
68+
A file stream to redirect stderr to. If none is specified it is set to `f_out`
69+
"""
70+
71+
if f_err is None:
72+
f_err = f_out
73+
74+
# save the file descriptors to restore to
75+
saved_stdout_fd = os.dup(sys.stdout.fileno())
76+
saved_stderr_fd = os.dup(sys.stderr.fileno())
77+
78+
# redirect the stdout/err streams
79+
redirectIO(f_out, f_err)
80+
81+
# yield to the with block
82+
yield
83+
84+
orig_out = sys.stdout.fileno()
85+
orig_err = sys.stderr.fileno()
86+
87+
# flush output
88+
sys.stderr.flush()
89+
sys.stdout.flush()
90+
91+
# close the output
92+
sys.stderr.close()
93+
sys.stdout.close()
94+
95+
os.dup2(saved_stdout_fd, orig_out)
96+
os.dup2(saved_stderr_fd, orig_err)
97+
98+
# reopen the standard streams with original file descriptors
99+
sys.stdout = io.TextIOWrapper(os.fdopen(orig_out, "wb"))
100+
sys.stderr = io.TextIOWrapper(os.fdopen(orig_err, "wb"))

0 commit comments

Comments
 (0)