##// END OF EJS Templates
Provide cleaner names for raw print utilities.
Fernando Perez -
Show More
@@ -1,294 +1,299 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2009 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12 from __future__ import print_function
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 import sys
18 18 import tempfile
19 19
20 20 from IPython.external.Itpl import itpl, printpl
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Code
24 24 #-----------------------------------------------------------------------------
25 25
26 26
27 27 class IOStream:
28 28
29 29 def __init__(self,stream,fallback):
30 30 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
31 31 stream = fallback
32 32 self.stream = stream
33 33 self._swrite = stream.write
34 34 self.flush = stream.flush
35 35
36 36 def write(self,data):
37 37 try:
38 38 self._swrite(data)
39 39 except:
40 40 try:
41 41 # print handles some unicode issues which may trip a plain
42 42 # write() call. Emulate write() by using an empty end
43 43 # argument.
44 44 print(data, end='', file=self.stream)
45 45 except:
46 46 # if we get here, something is seriously broken.
47 47 print('ERROR - failed to write data to stream:', self.stream,
48 48 file=sys.stderr)
49 49
50 50 # This class used to have a writeln method, but regular files and streams
51 51 # in Python don't have this method. We need to keep this completely
52 52 # compatible so we removed it.
53 53
54 54 def close(self):
55 55 pass
56 56
57 57
58 58 class IOTerm:
59 59 """ Term holds the file or file-like objects for handling I/O operations.
60 60
61 61 These are normally just sys.stdin, sys.stdout and sys.stderr but for
62 62 Windows they can can replaced to allow editing the strings before they are
63 63 displayed."""
64 64
65 65 # In the future, having IPython channel all its I/O operations through
66 66 # this class will make it easier to embed it into other environments which
67 67 # are not a normal terminal (such as a GUI-based shell)
68 68 def __init__(self, cin=None, cout=None, cerr=None):
69 69 self.cin = IOStream(cin, sys.stdin)
70 70 self.cout = IOStream(cout, sys.stdout)
71 71 self.cerr = IOStream(cerr, sys.stderr)
72 72
73 73
74 74 class Tee(object):
75 75 """A class to duplicate an output stream to stdout/err.
76 76
77 77 This works in a manner very similar to the Unix 'tee' command.
78 78
79 79 When the object is closed or deleted, it closes the original file given to
80 80 it for duplication.
81 81 """
82 82 # Inspired by:
83 83 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
84 84
85 85 def __init__(self, file_or_name, mode=None, channel='stdout'):
86 86 """Construct a new Tee object.
87 87
88 88 Parameters
89 89 ----------
90 90 file_or_name : filename or open filehandle (writable)
91 91 File that will be duplicated
92 92
93 93 mode : optional, valid mode for open().
94 94 If a filename was give, open with this mode.
95 95
96 96 channel : str, one of ['stdout', 'stderr']
97 97 """
98 98 if channel not in ['stdout', 'stderr']:
99 99 raise ValueError('Invalid channel spec %s' % channel)
100 100
101 101 if hasattr(file, 'write') and hasattr(file, 'seek'):
102 102 self.file = file_or_name
103 103 else:
104 104 self.file = open(file_or_name, mode)
105 105 self.channel = channel
106 106 self.ostream = getattr(sys, channel)
107 107 setattr(sys, channel, self)
108 108 self._closed = False
109 109
110 110 def close(self):
111 111 """Close the file and restore the channel."""
112 112 self.flush()
113 113 setattr(sys, self.channel, self.ostream)
114 114 self.file.close()
115 115 self._closed = True
116 116
117 117 def write(self, data):
118 118 """Write data to both channels."""
119 119 self.file.write(data)
120 120 self.ostream.write(data)
121 121 self.ostream.flush()
122 122
123 123 def flush(self):
124 124 """Flush both channels."""
125 125 self.file.flush()
126 126 self.ostream.flush()
127 127
128 128 def __del__(self):
129 129 if not self._closed:
130 130 self.close()
131 131
132 132
133 133 def file_read(filename):
134 134 """Read a file and close it. Returns the file source."""
135 135 fobj = open(filename,'r');
136 136 source = fobj.read();
137 137 fobj.close()
138 138 return source
139 139
140 140
141 141 def file_readlines(filename):
142 142 """Read a file and close it. Returns the file source using readlines()."""
143 143 fobj = open(filename,'r');
144 144 lines = fobj.readlines();
145 145 fobj.close()
146 146 return lines
147 147
148 148
149 149 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
150 150 """Take multiple lines of input.
151 151
152 152 A list with each line of input as a separate element is returned when a
153 153 termination string is entered (defaults to a single '.'). Input can also
154 154 terminate via EOF (^D in Unix, ^Z-RET in Windows).
155 155
156 156 Lines of input which end in \\ are joined into single entries (and a
157 157 secondary continuation prompt is issued as long as the user terminates
158 158 lines with \\). This allows entering very long strings which are still
159 159 meant to be treated as single entities.
160 160 """
161 161
162 162 try:
163 163 if header:
164 164 header += '\n'
165 165 lines = [raw_input(header + ps1)]
166 166 except EOFError:
167 167 return []
168 168 terminate = [terminate_str]
169 169 try:
170 170 while lines[-1:] != terminate:
171 171 new_line = raw_input(ps1)
172 172 while new_line.endswith('\\'):
173 173 new_line = new_line[:-1] + raw_input(ps2)
174 174 lines.append(new_line)
175 175
176 176 return lines[:-1] # don't return the termination command
177 177 except EOFError:
178 178 print
179 179 return lines
180 180
181 181
182 182 def raw_input_ext(prompt='', ps2='... '):
183 183 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
184 184
185 185 line = raw_input(prompt)
186 186 while line.endswith('\\'):
187 187 line = line[:-1] + raw_input(ps2)
188 188 return line
189 189
190 190
191 191 def ask_yes_no(prompt,default=None):
192 192 """Asks a question and returns a boolean (y/n) answer.
193 193
194 194 If default is given (one of 'y','n'), it is used if the user input is
195 195 empty. Otherwise the question is repeated until an answer is given.
196 196
197 197 An EOF is treated as the default answer. If there is no default, an
198 198 exception is raised to prevent infinite loops.
199 199
200 200 Valid answers are: y/yes/n/no (match is not case sensitive)."""
201 201
202 202 answers = {'y':True,'n':False,'yes':True,'no':False}
203 203 ans = None
204 204 while ans not in answers.keys():
205 205 try:
206 206 ans = raw_input(prompt+' ').lower()
207 207 if not ans: # response was an empty string
208 208 ans = default
209 209 except KeyboardInterrupt:
210 210 pass
211 211 except EOFError:
212 212 if default in answers.keys():
213 213 ans = default
214 214 print
215 215 else:
216 216 raise
217 217
218 218 return answers[ans]
219 219
220 220
221 221 class NLprinter:
222 222 """Print an arbitrarily nested list, indicating index numbers.
223 223
224 224 An instance of this class called nlprint is available and callable as a
225 225 function.
226 226
227 227 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
228 228 and using 'sep' to separate the index from the value. """
229 229
230 230 def __init__(self):
231 231 self.depth = 0
232 232
233 233 def __call__(self,lst,pos='',**kw):
234 234 """Prints the nested list numbering levels."""
235 235 kw.setdefault('indent',' ')
236 236 kw.setdefault('sep',': ')
237 237 kw.setdefault('start',0)
238 238 kw.setdefault('stop',len(lst))
239 239 # we need to remove start and stop from kw so they don't propagate
240 240 # into a recursive call for a nested list.
241 241 start = kw['start']; del kw['start']
242 242 stop = kw['stop']; del kw['stop']
243 243 if self.depth == 0 and 'header' in kw.keys():
244 244 print(kw['header'])
245 245
246 246 for idx in range(start,stop):
247 247 elem = lst[idx]
248 248 if type(elem)==type([]):
249 249 self.depth += 1
250 250 self.__call__(elem,itpl('$pos$idx,'),**kw)
251 251 self.depth -= 1
252 252 else:
253 253 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
254 254
255 255 nlprint = NLprinter()
256 256
257 257
258 258 def temp_pyfile(src, ext='.py'):
259 259 """Make a temporary python file, return filename and filehandle.
260 260
261 261 Parameters
262 262 ----------
263 263 src : string or list of strings (no need for ending newlines if list)
264 264 Source code to be written to the file.
265 265
266 266 ext : optional, string
267 267 Extension for the generated file.
268 268
269 269 Returns
270 270 -------
271 271 (filename, open filehandle)
272 272 It is the caller's responsibility to close the open file and unlink it.
273 273 """
274 274 fname = tempfile.mkstemp(ext)[1]
275 275 f = open(fname,'w')
276 276 f.write(src)
277 277 f.flush()
278 278 return fname, f
279 279
280 280
281 def rprint(*args, **kw):
282 """Raw print to sys.__stdout__"""
281 def raw_print(*args, **kw):
282 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
283 283
284 284 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
285 285 file=sys.__stdout__)
286 286 sys.__stdout__.flush()
287 287
288 288
289 def rprinte(*args, **kw):
290 """Raw print to sys.__stderr__"""
289 def raw_print_err(*args, **kw):
290 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
291 291
292 292 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
293 293 file=sys.__stderr__)
294 294 sys.__stderr__.flush()
295
296
297 # Short aliases for quick debugging, do NOT use these in production code.
298 rprint = raw_print
299 rprinte = raw_print_err
General Comments 0
You need to be logged in to leave comments. Login now