blob: a83adc8de2b99094a142d258835e061eec91f13f [file] [log] [blame]
Tor Norbyec667c1f2014-05-28 17:06:51 -07001import pydevd_constants #@UnusedImport -- defines False and True if not there.
2
3IS_PY3K = pydevd_constants.IS_PY3K
4
Tor Norbye3a2425a2013-11-04 10:16:08 -08005class IORedirector:
6 '''This class works to redirect the write function to many streams
7 '''
Tor Norbyec667c1f2014-05-28 17:06:51 -07008
Tor Norbye3a2425a2013-11-04 10:16:08 -08009 def __init__(self, *args):
10 self._redirectTo = args
Tor Norbyec667c1f2014-05-28 17:06:51 -070011
Tor Norbye3a2425a2013-11-04 10:16:08 -080012 def write(self, s):
13 for r in self._redirectTo:
14 try:
15 r.write(s)
16 except:
17 pass
18
19 def isatty(self):
Tor Norbyec667c1f2014-05-28 17:06:51 -070020 return False
Tor Norbye3a2425a2013-11-04 10:16:08 -080021
22 def flush(self):
23 for r in self._redirectTo:
24 r.flush()
25
26 def __getattr__(self, name):
27 for r in self._redirectTo:
28 if hasattr(r, name):
29 return r.__getattribute__(name)
30 raise AttributeError(name)
31
32class IOBuf:
33 '''This class works as a replacement for stdio and stderr.
34 It is a buffer and when its contents are requested, it will erase what
35
36 it has so far so that the next return will not return the same contents again.
37 '''
38 def __init__(self):
39 self.buflist = []
Tor Norbyec667c1f2014-05-28 17:06:51 -070040 import os
41 self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8')
42
Tor Norbye3a2425a2013-11-04 10:16:08 -080043 def getvalue(self):
44 b = self.buflist
45 self.buflist = [] #clear it
46 return ''.join(b)
47
48 def write(self, s):
Tor Norbyec667c1f2014-05-28 17:06:51 -070049 if not IS_PY3K:
50 if isinstance(s, unicode):
51 s = s.encode(self.encoding)
Tor Norbye3a2425a2013-11-04 10:16:08 -080052 self.buflist.append(s)
53
54 def isatty(self):
Tor Norbyec667c1f2014-05-28 17:06:51 -070055 return False
Tor Norbye3a2425a2013-11-04 10:16:08 -080056
57 def flush(self):
58 pass
59
60
61class _RedirectionsHolder:
62 _stack_stdout = []
63 _stack_stderr = []
64
65
66def StartRedirect(keep_original_redirection=False, std='stdout'):
67 '''
68 @param std: 'stdout', 'stderr', or 'both'
69 '''
70 import sys
71 buf = IOBuf()
72
73 if std == 'both':
74 config_stds = ['stdout', 'stderr']
75 else:
76 config_stds = [std]
77
78 for std in config_stds:
79 original = getattr(sys, std)
80 stack = getattr(_RedirectionsHolder, '_stack_%s' % std)
81 stack.append(original)
82
83 if keep_original_redirection:
84 setattr(sys, std, IORedirector(buf, getattr(sys, std)))
85 else:
86 setattr(sys, std, buf)
87 return buf
88
89
90def EndRedirect(std='stdout'):
91 import sys
92 if std == 'both':
93 config_stds = ['stdout', 'stderr']
94 else:
95 config_stds = [std]
96 for std in config_stds:
97 stack = getattr(_RedirectionsHolder, '_stack_%s' % std)
98 setattr(sys, std, stack.pop())
99