##// END OF EJS Templates
remove code deprecated since at least IPython 5.0
Matthias Bussonnier -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,60 +1,60 b''
1 1 name: Run tests
2 2
3 3 on:
4 4 push:
5 5 pull_request:
6 6 # Run weekly on Monday at 1:23 UTC
7 7 schedule:
8 8 - cron: '23 1 * * 1'
9 9 workflow_dispatch:
10 10
11 11
12 12 jobs:
13 13 test:
14 14 runs-on: ${{ matrix.os }}
15 15 strategy:
16 16 matrix:
17 17 os: [ubuntu-latest, windows-latest]
18 18 python-version: ["3.8", "3.9", "3.10"]
19 19 deps: [test_extra]
20 20 # Test all on ubuntu, test ends on macos
21 21 include:
22 22 - os: macos-latest
23 23 python-version: "3.8"
24 24 deps: test_extra
25 25 - os: macos-latest
26 26 python-version: "3.10"
27 27 deps: test_extra
28 28 # Tests minimal dependencies set
29 29 - os: ubuntu-latest
30 30 python-version: "3.10"
31 31 deps: test
32 32 # Tests latest development Python version
33 33 - os: ubuntu-latest
34 34 python-version: "3.11-dev"
35 35 deps: test
36 36
37 37 steps:
38 38 - uses: actions/checkout@v2
39 39 - name: Set up Python ${{ matrix.python-version }}
40 40 uses: actions/setup-python@v2
41 41 with:
42 42 python-version: ${{ matrix.python-version }}
43 43 - name: Install latex
44 44 if: runner.os == 'Linux' && matrix.deps == 'test_extra'
45 45 run: sudo apt-get -yq -o Acquire::Retries=3 --no-install-suggests --no-install-recommends install texlive dvipng
46 46 - name: Install and update Python dependencies
47 47 run: |
48 48 python -m pip install --upgrade pip setuptools wheel
49 49 python -m pip install --upgrade -e .[${{ matrix.deps }}]
50 50 python -m pip install --upgrade check-manifest pytest-cov
51 51 - name: Check manifest
52 52 if: runner.os != 'Windows' # setup.py does not support sdist on Windows
53 53 run: check-manifest
54 54 - name: pytest
55 55 env:
56 56 COLUMNS: 120
57 57 run: |
58 pytest --color=yes -ra -v --cov --cov-report=xml
58 pytest --color=yes -raXxs --cov --cov-report=xml
59 59 - name: Upload coverage to Codecov
60 60 uses: codecov/codecov-action@v2
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,187 +1,187 b''
1 1 """Tests for various magic functions specific to the terminal frontend."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 import sys
8 8 from io import StringIO
9 9 from unittest import TestCase
10 10
11 11 from IPython.testing import tools as tt
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Test functions begin
15 15 #-----------------------------------------------------------------------------
16 16
17 17 def check_cpaste(code, should_fail=False):
18 18 """Execute code via 'cpaste' and ensure it was executed, unless
19 19 should_fail is set.
20 20 """
21 21 ip.user_ns['code_ran'] = False
22 22
23 23 src = StringIO()
24 24 src.write(code)
25 25 src.write('\n--\n')
26 26 src.seek(0)
27 27
28 28 stdin_save = sys.stdin
29 29 sys.stdin = src
30 30
31 31 try:
32 32 context = tt.AssertPrints if should_fail else tt.AssertNotPrints
33 33 with context("Traceback (most recent call last)"):
34 34 ip.magic('cpaste')
35 35
36 36 if not should_fail:
37 37 assert ip.user_ns['code_ran'], "%r failed" % code
38 38 finally:
39 39 sys.stdin = stdin_save
40 40
41 41 def test_cpaste():
42 42 """Test cpaste magic"""
43 43
44 44 def runf():
45 45 """Marker function: sets a flag when executed.
46 46 """
47 47 ip.user_ns['code_ran'] = True
48 48 return 'runf' # return string so '+ runf()' doesn't result in success
49 49
50 50 tests = {'pass': ["runf()",
51 51 "In [1]: runf()",
52 52 "In [1]: if 1:\n ...: runf()",
53 53 "> > > runf()",
54 54 ">>> runf()",
55 55 " >>> runf()",
56 56 ],
57 57
58 58 'fail': ["1 + runf()",
59 59 "++ runf()",
60 60 ]}
61 61
62 62 ip.user_ns['runf'] = runf
63 63
64 64 for code in tests['pass']:
65 65 check_cpaste(code)
66 66
67 67 for code in tests['fail']:
68 68 check_cpaste(code, should_fail=True)
69 69
70 70
71 71 class PasteTestCase(TestCase):
72 72 """Multiple tests for clipboard pasting"""
73 73
74 74 def paste(self, txt, flags='-q'):
75 75 """Paste input text, by default in quiet mode"""
76 76 ip.hooks.clipboard_get = lambda : txt
77 77 ip.magic('paste '+flags)
78 78
79 79 def setUp(self):
80 80 # Inject fake clipboard hook but save original so we can restore it later
81 81 self.original_clip = ip.hooks.clipboard_get
82 82
83 83 def tearDown(self):
84 84 # Restore original hook
85 85 ip.hooks.clipboard_get = self.original_clip
86 86
87 87 def test_paste(self):
88 88 ip.user_ns.pop("x", None)
89 89 self.paste("x = 1")
90 90 self.assertEqual(ip.user_ns["x"], 1)
91 91 ip.user_ns.pop("x")
92 92
93 93 def test_paste_pyprompt(self):
94 94 ip.user_ns.pop("x", None)
95 95 self.paste(">>> x=2")
96 96 self.assertEqual(ip.user_ns["x"], 2)
97 97 ip.user_ns.pop("x")
98 98
99 99 def test_paste_py_multi(self):
100 100 self.paste("""
101 101 >>> x = [1,2,3]
102 102 >>> y = []
103 103 >>> for i in x:
104 104 ... y.append(i**2)
105 105 ...
106 106 """
107 107 )
108 108 self.assertEqual(ip.user_ns["x"], [1, 2, 3])
109 109 self.assertEqual(ip.user_ns["y"], [1, 4, 9])
110 110
111 111 def test_paste_py_multi_r(self):
112 112 "Now, test that self.paste -r works"
113 113 self.test_paste_py_multi()
114 114 self.assertEqual(ip.user_ns.pop("x"), [1, 2, 3])
115 115 self.assertEqual(ip.user_ns.pop("y"), [1, 4, 9])
116 116 self.assertFalse("x" in ip.user_ns)
117 117 ip.magic("paste -r")
118 118 self.assertEqual(ip.user_ns["x"], [1, 2, 3])
119 119 self.assertEqual(ip.user_ns["y"], [1, 4, 9])
120 120
121 121 def test_paste_email(self):
122 122 "Test pasting of email-quoted contents"
123 123 self.paste("""\
124 124 >> def foo(x):
125 125 >> return x + 1
126 126 >> xx = foo(1.1)"""
127 127 )
128 128 self.assertEqual(ip.user_ns["xx"], 2.1)
129 129
130 130 def test_paste_email2(self):
131 131 "Email again; some programs add a space also at each quoting level"
132 132 self.paste("""\
133 133 > > def foo(x):
134 134 > > return x + 1
135 135 > > yy = foo(2.1) """
136 136 )
137 137 self.assertEqual(ip.user_ns["yy"], 3.1)
138 138
139 139 def test_paste_email_py(self):
140 140 "Email quoting of interactive input"
141 141 self.paste("""\
142 142 >> >>> def f(x):
143 143 >> ... return x+1
144 144 >> ...
145 145 >> >>> zz = f(2.5) """
146 146 )
147 147 self.assertEqual(ip.user_ns["zz"], 3.5)
148 148
149 149 def test_paste_echo(self):
150 150 "Also test self.paste echoing, by temporarily faking the writer"
151 151 w = StringIO()
152 writer = ip.write
153 ip.write = w.write
152 old_write = sys.stdout.write
153 sys.stdout.write = w.write
154 154 code = """
155 155 a = 100
156 156 b = 200"""
157 157 try:
158 158 self.paste(code,'')
159 159 out = w.getvalue()
160 160 finally:
161 ip.write = writer
161 sys.stdout.write = old_write
162 162 self.assertEqual(ip.user_ns["a"], 100)
163 163 self.assertEqual(ip.user_ns["b"], 200)
164 164 assert out == code + "\n## -- End pasted text --\n"
165 165
166 166 def test_paste_leading_commas(self):
167 167 "Test multiline strings with leading commas"
168 168 tm = ip.magics_manager.registry['TerminalMagics']
169 169 s = '''\
170 170 a = """
171 171 ,1,2,3
172 172 """'''
173 173 ip.user_ns.pop("foo", None)
174 174 tm.store_or_execute(s, "foo")
175 175 self.assertIn("foo", ip.user_ns)
176 176
177 177 def test_paste_trailing_question(self):
178 178 "Test pasting sources with trailing question marks"
179 179 tm = ip.magics_manager.registry['TerminalMagics']
180 180 s = '''\
181 181 def funcfoo():
182 182 if True: #am i true?
183 183 return 'fooresult'
184 184 '''
185 185 ip.user_ns.pop('funcfoo', None)
186 186 self.paste(s)
187 187 self.assertEqual(ip.user_ns["funcfoo"](), "fooresult")
@@ -1,215 +1,214 b''
1 1 """Extra magics for terminal use."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6
7 7 from logging import error
8 8 import os
9 9 import sys
10 10
11 11 from IPython.core.error import TryNext, UsageError
12 12 from IPython.core.magic import Magics, magics_class, line_magic
13 13 from IPython.lib.clipboard import ClipboardEmpty
14 14 from IPython.testing.skipdoctest import skip_doctest
15 15 from IPython.utils.text import SList, strip_email_quotes
16 16 from IPython.utils import py3compat
17 17
18 18 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
19 19 """ Yield pasted lines until the user enters the given sentinel value.
20 20 """
21 21 if not quiet:
22 22 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
23 23 % sentinel)
24 24 prompt = ":"
25 25 else:
26 26 prompt = ""
27 27 while True:
28 28 try:
29 29 l = l_input(prompt)
30 30 if l == sentinel:
31 31 return
32 32 else:
33 33 yield l
34 34 except EOFError:
35 35 print('<EOF>')
36 36 return
37 37
38 38
39 39 @magics_class
40 40 class TerminalMagics(Magics):
41 41 def __init__(self, shell):
42 42 super(TerminalMagics, self).__init__(shell)
43 43
44 44 def store_or_execute(self, block, name):
45 45 """ Execute a block, or store it in a variable, per the user's request.
46 46 """
47 47 if name:
48 48 # If storing it for further editing
49 49 self.shell.user_ns[name] = SList(block.splitlines())
50 50 print("Block assigned to '%s'" % name)
51 51 else:
52 52 b = self.preclean_input(block)
53 53 self.shell.user_ns['pasted_block'] = b
54 54 self.shell.using_paste_magics = True
55 55 try:
56 56 self.shell.run_cell(b)
57 57 finally:
58 58 self.shell.using_paste_magics = False
59 59
60 60 def preclean_input(self, block):
61 61 lines = block.splitlines()
62 62 while lines and not lines[0].strip():
63 63 lines = lines[1:]
64 64 return strip_email_quotes('\n'.join(lines))
65 65
66 66 def rerun_pasted(self, name='pasted_block'):
67 67 """ Rerun a previously pasted command.
68 68 """
69 69 b = self.shell.user_ns.get(name)
70 70
71 71 # Sanity checks
72 72 if b is None:
73 73 raise UsageError('No previous pasted block available')
74 74 if not isinstance(b, str):
75 75 raise UsageError(
76 76 "Variable 'pasted_block' is not a string, can't execute")
77 77
78 78 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
79 79 self.shell.run_cell(b)
80 80
81 81 @line_magic
82 82 def autoindent(self, parameter_s = ''):
83 83 """Toggle autoindent on/off (deprecated)"""
84 84 self.shell.set_autoindent()
85 85 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
86 86
87 87 @skip_doctest
88 88 @line_magic
89 89 def cpaste(self, parameter_s=''):
90 90 """Paste & execute a pre-formatted code block from clipboard.
91 91
92 92 You must terminate the block with '--' (two minus-signs) or Ctrl-D
93 93 alone on the line. You can also provide your own sentinel with '%paste
94 94 -s %%' ('%%' is the new sentinel for this operation).
95 95
96 96 The block is dedented prior to execution to enable execution of method
97 97 definitions. '>' and '+' characters at the beginning of a line are
98 98 ignored, to allow pasting directly from e-mails, diff files and
99 99 doctests (the '...' continuation prompt is also stripped). The
100 100 executed block is also assigned to variable named 'pasted_block' for
101 101 later editing with '%edit pasted_block'.
102 102
103 103 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
104 104 This assigns the pasted block to variable 'foo' as string, without
105 105 dedenting or executing it (preceding >>> and + is still stripped)
106 106
107 107 '%cpaste -r' re-executes the block previously entered by cpaste.
108 108 '%cpaste -q' suppresses any additional output messages.
109 109
110 110 Do not be alarmed by garbled output on Windows (it's a readline bug).
111 111 Just press enter and type -- (and press enter again) and the block
112 112 will be what was just pasted.
113 113
114 114 Shell escapes are not supported (yet).
115 115
116 116 See also
117 117 --------
118 118 paste: automatically pull code from clipboard.
119 119
120 120 Examples
121 121 --------
122 122 ::
123 123
124 124 In [8]: %cpaste
125 125 Pasting code; enter '--' alone on the line to stop.
126 126 :>>> a = ["world!", "Hello"]
127 127 :>>> print(" ".join(sorted(a)))
128 128 :--
129 129 Hello world!
130 130
131 131 ::
132 132 In [8]: %cpaste
133 133 Pasting code; enter '--' alone on the line to stop.
134 134 :>>> %alias_magic t timeit
135 135 :>>> %t -n1 pass
136 136 :--
137 137 Created `%t` as an alias for `%timeit`.
138 138 Created `%%t` as an alias for `%%timeit`.
139 139 354 ns Β± 224 ns per loop (mean Β± std. dev. of 7 runs, 1 loop each)
140 140 """
141 141 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
142 142 if 'r' in opts:
143 143 self.rerun_pasted()
144 144 return
145 145
146 146 quiet = ('q' in opts)
147 147
148 148 sentinel = opts.get('s', u'--')
149 149 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
150 150 self.store_or_execute(block, name)
151 151
152 152 @line_magic
153 153 def paste(self, parameter_s=''):
154 154 """Paste & execute a pre-formatted code block from clipboard.
155 155
156 156 The text is pulled directly from the clipboard without user
157 157 intervention and printed back on the screen before execution (unless
158 158 the -q flag is given to force quiet mode).
159 159
160 160 The block is dedented prior to execution to enable execution of method
161 161 definitions. '>' and '+' characters at the beginning of a line are
162 162 ignored, to allow pasting directly from e-mails, diff files and
163 163 doctests (the '...' continuation prompt is also stripped). The
164 164 executed block is also assigned to variable named 'pasted_block' for
165 165 later editing with '%edit pasted_block'.
166 166
167 167 You can also pass a variable name as an argument, e.g. '%paste foo'.
168 168 This assigns the pasted block to variable 'foo' as string, without
169 169 executing it (preceding >>> and + is still stripped).
170 170
171 171 Options:
172 172
173 173 -r: re-executes the block previously entered by cpaste.
174 174
175 175 -q: quiet mode: do not echo the pasted text back to the terminal.
176 176
177 177 IPython statements (magics, shell escapes) are not supported (yet).
178 178
179 179 See also
180 180 --------
181 181 cpaste: manually paste code into terminal until you mark its end.
182 182 """
183 183 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
184 184 if 'r' in opts:
185 185 self.rerun_pasted()
186 186 return
187 187 try:
188 188 block = self.shell.hooks.clipboard_get()
189 189 except TryNext as clipboard_exc:
190 190 message = getattr(clipboard_exc, 'args')
191 191 if message:
192 192 error(message[0])
193 193 else:
194 194 error('Could not get text from the clipboard.')
195 195 return
196 196 except ClipboardEmpty as e:
197 197 raise UsageError("The clipboard appears to be empty") from e
198 198
199 199 # By default, echo back to terminal unless quiet mode is requested
200 200 if 'q' not in opts:
201 write = self.shell.write
202 write(self.shell.pycolorize(block))
203 if not block.endswith('\n'):
204 write('\n')
205 write("## -- End pasted text --\n")
201 sys.stdout.write(self.shell.pycolorize(block))
202 if not block.endswith("\n"):
203 sys.stdout.write("\n")
204 sys.stdout.write("## -- End pasted text --\n")
206 205
207 206 self.store_or_execute(block, name)
208 207
209 208 # Class-level: add a '%cls' magic only on Windows
210 209 if sys.platform == 'win32':
211 210 @line_magic
212 211 def cls(self, s):
213 212 """Clear screen.
214 213 """
215 214 os.system("cls")
@@ -1,246 +1,241 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 pathlib import Path
17 17 from warnings import warn
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 mode : optional, valid mode for open().
118 118 If a filename was give, open with this mode.
119 119 channel : str, one of ['stdout', 'stderr']
120 120 """
121 121 if channel not in ['stdout', 'stderr']:
122 122 raise ValueError('Invalid channel spec %s' % channel)
123 123
124 124 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
125 125 self.file = file_or_name
126 126 else:
127 127 self.file = open(file_or_name, mode)
128 128 self.channel = channel
129 129 self.ostream = getattr(sys, channel)
130 130 setattr(sys, channel, self)
131 131 self._closed = False
132 132
133 133 def close(self):
134 134 """Close the file and restore the channel."""
135 135 self.flush()
136 136 setattr(sys, self.channel, self.ostream)
137 137 self.file.close()
138 138 self._closed = True
139 139
140 140 def write(self, data):
141 141 """Write data to both channels."""
142 142 self.file.write(data)
143 143 self.ostream.write(data)
144 144 self.ostream.flush()
145 145
146 146 def flush(self):
147 147 """Flush both channels."""
148 148 self.file.flush()
149 149 self.ostream.flush()
150 150
151 151 def __del__(self):
152 152 if not self._closed:
153 153 self.close()
154 154
155 155
156 156 def ask_yes_no(prompt, default=None, interrupt=None):
157 157 """Asks a question and returns a boolean (y/n) answer.
158 158
159 159 If default is given (one of 'y','n'), it is used if the user input is
160 160 empty. If interrupt is given (one of 'y','n'), it is used if the user
161 161 presses Ctrl-C. Otherwise the question is repeated until an answer is
162 162 given.
163 163
164 164 An EOF is treated as the default answer. If there is no default, an
165 165 exception is raised to prevent infinite loops.
166 166
167 167 Valid answers are: y/yes/n/no (match is not case sensitive)."""
168 168
169 169 answers = {'y':True,'n':False,'yes':True,'no':False}
170 170 ans = None
171 171 while ans not in answers.keys():
172 172 try:
173 173 ans = input(prompt+' ').lower()
174 174 if not ans: # response was an empty string
175 175 ans = default
176 176 except KeyboardInterrupt:
177 177 if interrupt:
178 178 ans = interrupt
179 179 print("\r")
180 180 except EOFError:
181 181 if default in answers.keys():
182 182 ans = default
183 183 print()
184 184 else:
185 185 raise
186 186
187 187 return answers[ans]
188 188
189 189
190 190 def temp_pyfile(src, ext='.py'):
191 191 """Make a temporary python file, return filename and filehandle.
192 192
193 193 Parameters
194 194 ----------
195 195 src : string or list of strings (no need for ending newlines if list)
196 196 Source code to be written to the file.
197 197 ext : optional, string
198 198 Extension for the generated file.
199 199
200 200 Returns
201 201 -------
202 202 (filename, open filehandle)
203 203 It is the caller's responsibility to close the open file and unlink it.
204 204 """
205 205 fname = tempfile.mkstemp(ext)[1]
206 206 with open(Path(fname), "w") as f:
207 207 f.write(src)
208 208 f.flush()
209 209 return fname
210 210
211 211 @undoc
212 212 def atomic_writing(*args, **kwargs):
213 213 """DEPRECATED: moved to notebook.services.contents.fileio"""
214 214 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio since IPython 4.0", DeprecationWarning, stacklevel=2)
215 215 from notebook.services.contents.fileio import atomic_writing
216 216 return atomic_writing(*args, **kwargs)
217 217
218 218 @undoc
219 219 def raw_print(*args, **kw):
220 220 """DEPRECATED: Raw print to sys.__stdout__, otherwise identical interface to print()."""
221 221 warn("IPython.utils.io.raw_print has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
222 222
223 223 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
224 224 file=sys.__stdout__)
225 225 sys.__stdout__.flush()
226 226
227 227 @undoc
228 228 def raw_print_err(*args, **kw):
229 229 """DEPRECATED: Raw print to sys.__stderr__, otherwise identical interface to print()."""
230 230 warn("IPython.utils.io.raw_print_err has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
231 231
232 232 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
233 233 file=sys.__stderr__)
234 234 sys.__stderr__.flush()
235 235
236 # used by IPykernel <- 4.9. Removed during IPython 7-dev period and re-added
237 # Keep for a version or two then should remove
238 rprint = raw_print
239 rprinte = raw_print_err
240
241 236 @undoc
242 237 def unicode_std_stream(stream='stdout'):
243 238 """DEPRECATED, moved to nbconvert.utils.io"""
244 239 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io since IPython 4.0", DeprecationWarning, stacklevel=2)
245 240 from nbconvert.utils.io import unicode_std_stream
246 241 return unicode_std_stream(stream)
General Comments 0
You need to be logged in to leave comments. Login now