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