##// END OF EJS Templates
Insert a new line after catching KeyboardException in ask_yes_no...
sachet-mittal -
Show More
@@ -1,239 +1,240 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9
10 10
11 11 import atexit
12 12 import os
13 13 import sys
14 14 import tempfile
15 15 import warnings
16 16 from warnings import warn
17 17
18 18 from IPython.utils.decorators import undoc
19 19 from .capture import CapturedIO, capture_output
20 20 from .py3compat import string_types, input, PY3
21 21
22 22 @undoc
23 23 class IOStream:
24 24
25 25 def __init__(self, stream, fallback=None):
26 26 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
27 27 DeprecationWarning, stacklevel=2)
28 28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
29 29 if fallback is not None:
30 30 stream = fallback
31 31 else:
32 32 raise ValueError("fallback required, but not specified")
33 33 self.stream = stream
34 34 self._swrite = stream.write
35 35
36 36 # clone all methods not overridden:
37 37 def clone(meth):
38 38 return not hasattr(self, meth) and not meth.startswith('_')
39 39 for meth in filter(clone, dir(stream)):
40 40 setattr(self, meth, getattr(stream, meth))
41 41
42 42 def __repr__(self):
43 43 cls = self.__class__
44 44 tpl = '{mod}.{cls}({args})'
45 45 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
46 46
47 47 def write(self,data):
48 48 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
49 49 DeprecationWarning, stacklevel=2)
50 50 try:
51 51 self._swrite(data)
52 52 except:
53 53 try:
54 54 # print handles some unicode issues which may trip a plain
55 55 # write() call. Emulate write() by using an empty end
56 56 # argument.
57 57 print(data, end='', file=self.stream)
58 58 except:
59 59 # if we get here, something is seriously broken.
60 60 print('ERROR - failed to write data to stream:', self.stream,
61 61 file=sys.stderr)
62 62
63 63 def writelines(self, lines):
64 64 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
65 65 DeprecationWarning, stacklevel=2)
66 66 if isinstance(lines, string_types):
67 67 lines = [lines]
68 68 for line in lines:
69 69 self.write(line)
70 70
71 71 # This class used to have a writeln method, but regular files and streams
72 72 # in Python don't have this method. We need to keep this completely
73 73 # compatible so we removed it.
74 74
75 75 @property
76 76 def closed(self):
77 77 return self.stream.closed
78 78
79 79 def close(self):
80 80 pass
81 81
82 82 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
83 83 devnull = open(os.devnull, 'w')
84 84 atexit.register(devnull.close)
85 85
86 86 # io.std* are deprecated, but don't show our own deprecation warnings
87 87 # during initialization of the deprecated API.
88 88 with warnings.catch_warnings():
89 89 warnings.simplefilter('ignore', DeprecationWarning)
90 90 stdin = IOStream(sys.stdin, fallback=devnull)
91 91 stdout = IOStream(sys.stdout, fallback=devnull)
92 92 stderr = IOStream(sys.stderr, fallback=devnull)
93 93
94 94 class Tee(object):
95 95 """A class to duplicate an output stream to stdout/err.
96 96
97 97 This works in a manner very similar to the Unix 'tee' command.
98 98
99 99 When the object is closed or deleted, it closes the original file given to
100 100 it for duplication.
101 101 """
102 102 # Inspired by:
103 103 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
104 104
105 105 def __init__(self, file_or_name, mode="w", channel='stdout'):
106 106 """Construct a new Tee object.
107 107
108 108 Parameters
109 109 ----------
110 110 file_or_name : filename or open filehandle (writable)
111 111 File that will be duplicated
112 112
113 113 mode : optional, valid mode for open().
114 114 If a filename was give, open with this mode.
115 115
116 116 channel : str, one of ['stdout', 'stderr']
117 117 """
118 118 if channel not in ['stdout', 'stderr']:
119 119 raise ValueError('Invalid channel spec %s' % channel)
120 120
121 121 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
122 122 self.file = file_or_name
123 123 else:
124 124 self.file = open(file_or_name, mode)
125 125 self.channel = channel
126 126 self.ostream = getattr(sys, channel)
127 127 setattr(sys, channel, self)
128 128 self._closed = False
129 129
130 130 def close(self):
131 131 """Close the file and restore the channel."""
132 132 self.flush()
133 133 setattr(sys, self.channel, self.ostream)
134 134 self.file.close()
135 135 self._closed = True
136 136
137 137 def write(self, data):
138 138 """Write data to both channels."""
139 139 self.file.write(data)
140 140 self.ostream.write(data)
141 141 self.ostream.flush()
142 142
143 143 def flush(self):
144 144 """Flush both channels."""
145 145 self.file.flush()
146 146 self.ostream.flush()
147 147
148 148 def __del__(self):
149 149 if not self._closed:
150 150 self.close()
151 151
152 152
153 153 def ask_yes_no(prompt, default=None, interrupt=None):
154 154 """Asks a question and returns a boolean (y/n) answer.
155 155
156 156 If default is given (one of 'y','n'), it is used if the user input is
157 157 empty. If interrupt is given (one of 'y','n'), it is used if the user
158 158 presses Ctrl-C. Otherwise the question is repeated until an answer is
159 159 given.
160 160
161 161 An EOF is treated as the default answer. If there is no default, an
162 162 exception is raised to prevent infinite loops.
163 163
164 164 Valid answers are: y/yes/n/no (match is not case sensitive)."""
165 165
166 166 answers = {'y':True,'n':False,'yes':True,'no':False}
167 167 ans = None
168 168 while ans not in answers.keys():
169 169 try:
170 170 ans = input(prompt+' ').lower()
171 171 if not ans: # response was an empty string
172 172 ans = default
173 173 except KeyboardInterrupt:
174 174 if interrupt:
175 175 ans = interrupt
176 print("\r")
176 177 except EOFError:
177 178 if default in answers.keys():
178 179 ans = default
179 180 print()
180 181 else:
181 182 raise
182 183
183 184 return answers[ans]
184 185
185 186
186 187 def temp_pyfile(src, ext='.py'):
187 188 """Make a temporary python file, return filename and filehandle.
188 189
189 190 Parameters
190 191 ----------
191 192 src : string or list of strings (no need for ending newlines if list)
192 193 Source code to be written to the file.
193 194
194 195 ext : optional, string
195 196 Extension for the generated file.
196 197
197 198 Returns
198 199 -------
199 200 (filename, open filehandle)
200 201 It is the caller's responsibility to close the open file and unlink it.
201 202 """
202 203 fname = tempfile.mkstemp(ext)[1]
203 204 f = open(fname,'w')
204 205 f.write(src)
205 206 f.flush()
206 207 return fname, f
207 208
208 209 def atomic_writing(*args, **kwargs):
209 210 """DEPRECATED: moved to notebook.services.contents.fileio"""
210 211 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio")
211 212 from notebook.services.contents.fileio import atomic_writing
212 213 return atomic_writing(*args, **kwargs)
213 214
214 215 def raw_print(*args, **kw):
215 216 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
216 217
217 218 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
218 219 file=sys.__stdout__)
219 220 sys.__stdout__.flush()
220 221
221 222
222 223 def raw_print_err(*args, **kw):
223 224 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
224 225
225 226 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
226 227 file=sys.__stderr__)
227 228 sys.__stderr__.flush()
228 229
229 230
230 231 # Short aliases for quick debugging, do NOT use these in production code.
231 232 rprint = raw_print
232 233 rprinte = raw_print_err
233 234
234 235
235 236 def unicode_std_stream(stream='stdout'):
236 237 """DEPRECATED, moved to nbconvert.utils.io"""
237 238 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io")
238 239 from nbconvert.utils.io import unicode_std_stream
239 240 return unicode_std_stream(stream)
General Comments 0
You need to be logged in to leave comments. Login now