Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief A :epkg:`*py:io:StringIO` which also outputs its content for a file.
4"""
5import os
6from io import StringIO
9class StringIOAndFile(StringIO):
10 """
11 Overloads a StringIO to also writes in a file.
12 """
14 def __init__(self, filename):
15 """
16 constructor
18 @param filename filename
19 """
20 StringIO.__init__(self)
21 self.filename = filename
22 if os.path.exists(filename):
23 os.remove(filename)
24 self.handle = None
25 self.redirect = {}
26 self.to = None
28 def write(self, s):
29 """
30 Appends a string.
32 @param s add a string to the stream
33 @return self
34 """
35 if self.to is not None:
36 self.redirect[self.to].write(s)
37 else:
38 StringIO.write(self, s)
39 if not self.handle:
40 self.handle = open(self.filename, "w",
41 encoding="utf-8", errors="ignore")
42 self.handle.write(s)
43 self.handle.flush()
44 return self
46 def flush(self):
47 """
48 Calls two flush.
49 """
50 StringIO.flush(self)
51 if self.handle:
52 self.handle.flush()
54 def close(self):
55 """
56 Calls two close.
57 """
58 StringIO.close(self)
59 if self.handle:
60 self.handle.close()
62 def begin_test(self, name):
63 """
64 Redirects output to a :epkg:`*py:io:StringIO`.
66 @param name name
67 """
68 if self.to is not None:
69 raise Exception( # pragma: no cover
70 "A test has not finished: '{0}'".format(self.to))
71 if name is None:
72 raise ValueError( # pragma: no cover
73 "name is None")
74 self.to = name
75 self.redirect[name] = StringIO()
77 def end_test(self, name):
78 """
79 Ends the redirection.
81 @param name name
82 """
83 if name != self.to:
84 raise ValueError( # pragma: no cover
85 "Inconsistency in test name '{0}' != '{1}'".format(
86 name, self.to))
87 self.to = None
89 def getvalue(self):
90 """
91 Returns the content of the buffer.
92 """
93 if self.to is not None:
94 return self.redirect[self.to].getvalue()
95 return StringIO.getvalue(self)