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