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