##// END OF EJS Templates
py3compat fixes for %%script and tests
MinRK -
Show More
@@ -1,215 +1,216 b''
1 """Magic functions for running cells in various scripts."""
1 """Magic functions for running cells in various scripts."""
2 #-----------------------------------------------------------------------------
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2012 The IPython Development Team.
3 # Copyright (c) 2012 The IPython Development Team.
4 #
4 #
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6 #
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 # Stdlib
14 # Stdlib
15 import os
15 import os
16 import re
16 import re
17 import sys
17 import sys
18 from subprocess import Popen, PIPE
18 from subprocess import Popen, PIPE
19
19
20 # Our own packages
20 # Our own packages
21 from IPython.config.configurable import Configurable
21 from IPython.config.configurable import Configurable
22 from IPython.core import magic_arguments
22 from IPython.core import magic_arguments
23 from IPython.core.error import UsageError
23 from IPython.core.error import UsageError
24 from IPython.core.magic import (
24 from IPython.core.magic import (
25 Magics, magics_class, line_magic, cell_magic
25 Magics, magics_class, line_magic, cell_magic
26 )
26 )
27 from IPython.lib.backgroundjobs import BackgroundJobManager
27 from IPython.lib.backgroundjobs import BackgroundJobManager
28 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.testing.skipdoctest import skip_doctest
29 from IPython.utils import py3compat
29 from IPython.utils import py3compat
30 from IPython.utils.process import find_cmd, FindCmdError, arg_split
30 from IPython.utils.process import find_cmd, FindCmdError, arg_split
31 from IPython.utils.traitlets import List, Dict
31 from IPython.utils.traitlets import List, Dict
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Magic implementation classes
34 # Magic implementation classes
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 def script_args(f):
37 def script_args(f):
38 """single decorator for adding script args"""
38 """single decorator for adding script args"""
39 args = [
39 args = [
40 magic_arguments.argument(
40 magic_arguments.argument(
41 '--out', type=str,
41 '--out', type=str,
42 help="""The variable in which to store stdout from the script.
42 help="""The variable in which to store stdout from the script.
43 If the script is backgrounded, this will be the stdout *pipe*,
43 If the script is backgrounded, this will be the stdout *pipe*,
44 instead of the stderr text itself.
44 instead of the stderr text itself.
45 """
45 """
46 ),
46 ),
47 magic_arguments.argument(
47 magic_arguments.argument(
48 '--err', type=str,
48 '--err', type=str,
49 help="""The variable in which to store stderr from the script.
49 help="""The variable in which to store stderr from the script.
50 If the script is backgrounded, this will be the stderr *pipe*,
50 If the script is backgrounded, this will be the stderr *pipe*,
51 instead of the stderr text itself.
51 instead of the stderr text itself.
52 """
52 """
53 ),
53 ),
54 magic_arguments.argument(
54 magic_arguments.argument(
55 '--bg', action="store_true",
55 '--bg', action="store_true",
56 help="""Whether to run the script in the background.
56 help="""Whether to run the script in the background.
57 If given, the only way to see the output of the command is
57 If given, the only way to see the output of the command is
58 with --out/err.
58 with --out/err.
59 """
59 """
60 ),
60 ),
61 ]
61 ]
62 for arg in args:
62 for arg in args:
63 f = arg(f)
63 f = arg(f)
64 return f
64 return f
65
65
66 @magics_class
66 @magics_class
67 class ScriptMagics(Magics, Configurable):
67 class ScriptMagics(Magics, Configurable):
68 """Magics for talking to scripts
68 """Magics for talking to scripts
69
69
70 This defines a base `%%script` cell magic for running a cell
70 This defines a base `%%script` cell magic for running a cell
71 with a program in a subprocess, and registers a few top-level
71 with a program in a subprocess, and registers a few top-level
72 magics that call %%script with common interpreters.
72 magics that call %%script with common interpreters.
73 """
73 """
74 script_magics = List(config=True,
74 script_magics = List(config=True,
75 help="""Extra script cell magics to define
75 help="""Extra script cell magics to define
76
76
77 This generates simple wrappers of `%%script foo` as `%%foo`.
77 This generates simple wrappers of `%%script foo` as `%%foo`.
78
78
79 If you want to add script magics that aren't on your path,
79 If you want to add script magics that aren't on your path,
80 specify them in script_paths
80 specify them in script_paths
81 """,
81 """,
82 )
82 )
83 def _script_magics_default(self):
83 def _script_magics_default(self):
84 """default to a common list of programs if we find them"""
84 """default to a common list of programs if we find them"""
85
85
86 defaults = []
86 defaults = []
87 to_try = []
87 to_try = []
88 if os.name == 'nt':
88 if os.name == 'nt':
89 defaults.append('cmd')
89 defaults.append('cmd')
90 to_try.append('powershell')
90 to_try.append('powershell')
91 to_try.extend([
91 to_try.extend([
92 'sh',
92 'sh',
93 'bash',
93 'bash',
94 'perl',
94 'perl',
95 'ruby',
95 'ruby',
96 'python3',
96 'python3',
97 'pypy',
97 'pypy',
98 ])
98 ])
99
99
100 for cmd in to_try:
100 for cmd in to_try:
101 if cmd in self.script_paths:
101 if cmd in self.script_paths:
102 defaults.append(cmd)
102 defaults.append(cmd)
103 else:
103 else:
104 try:
104 try:
105 find_cmd(cmd)
105 find_cmd(cmd)
106 except FindCmdError:
106 except FindCmdError:
107 # command not found, ignore it
107 # command not found, ignore it
108 pass
108 pass
109 except ImportError:
109 except ImportError:
110 # Windows without pywin32, find_cmd doesn't work
110 # Windows without pywin32, find_cmd doesn't work
111 pass
111 pass
112 else:
112 else:
113 defaults.append(cmd)
113 defaults.append(cmd)
114 return defaults
114 return defaults
115
115
116 script_paths = Dict(config=True,
116 script_paths = Dict(config=True,
117 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
117 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
118
118
119 Only necessary for items in script_magics where the default path will not
119 Only necessary for items in script_magics where the default path will not
120 find the right interpreter.
120 find the right interpreter.
121 """
121 """
122 )
122 )
123
123
124 def __init__(self, shell=None):
124 def __init__(self, shell=None):
125 Configurable.__init__(self, config=shell.config)
125 Configurable.__init__(self, config=shell.config)
126 self._generate_script_magics()
126 self._generate_script_magics()
127 Magics.__init__(self, shell=shell)
127 Magics.__init__(self, shell=shell)
128 self.job_manager = BackgroundJobManager()
128 self.job_manager = BackgroundJobManager()
129
129
130 def _generate_script_magics(self):
130 def _generate_script_magics(self):
131 cell_magics = self.magics['cell']
131 cell_magics = self.magics['cell']
132 for name in self.script_magics:
132 for name in self.script_magics:
133 cell_magics[name] = self._make_script_magic(name)
133 cell_magics[name] = self._make_script_magic(name)
134
134
135 def _make_script_magic(self, name):
135 def _make_script_magic(self, name):
136 """make a named magic, that calls %%script with a particular program"""
136 """make a named magic, that calls %%script with a particular program"""
137 # expand to explicit path if necessary:
137 # expand to explicit path if necessary:
138 script = self.script_paths.get(name, name)
138 script = self.script_paths.get(name, name)
139
139
140 @magic_arguments.magic_arguments()
140 @magic_arguments.magic_arguments()
141 @script_args
141 @script_args
142 def named_script_magic(line, cell):
142 def named_script_magic(line, cell):
143 # if line, add it as cl-flags
143 # if line, add it as cl-flags
144 if line:
144 if line:
145 line = "%s %s" % (script, line)
145 line = "%s %s" % (script, line)
146 else:
146 else:
147 line = script
147 line = script
148 return self.shebang(line, cell)
148 return self.shebang(line, cell)
149
149
150 # write a basic docstring:
150 # write a basic docstring:
151 named_script_magic.__doc__ = \
151 named_script_magic.__doc__ = \
152 """%%{name} script magic
152 """%%{name} script magic
153
153
154 Run cells with {script} in a subprocess.
154 Run cells with {script} in a subprocess.
155
155
156 This is a shortcut for `%%script {script}`
156 This is a shortcut for `%%script {script}`
157 """.format(**locals())
157 """.format(**locals())
158
158
159 return named_script_magic
159 return named_script_magic
160
160
161 @magic_arguments.magic_arguments()
161 @magic_arguments.magic_arguments()
162 @script_args
162 @script_args
163 @cell_magic("script")
163 @cell_magic("script")
164 def shebang(self, line, cell):
164 def shebang(self, line, cell):
165 """Run a cell via a shell command
165 """Run a cell via a shell command
166
166
167 The `%%script` line is like the #! line of script,
167 The `%%script` line is like the #! line of script,
168 specifying a program (bash, perl, ruby, etc.) with which to run.
168 specifying a program (bash, perl, ruby, etc.) with which to run.
169
169
170 The rest of the cell is run by that program.
170 The rest of the cell is run by that program.
171
171
172 Examples
172 Examples
173 --------
173 --------
174 ::
174 ::
175
175
176 In [1]: %%script bash
176 In [1]: %%script bash
177 ...: for i in 1 2 3; do
177 ...: for i in 1 2 3; do
178 ...: echo $i
178 ...: echo $i
179 ...: done
179 ...: done
180 1
180 1
181 2
181 2
182 3
182 3
183 """
183 """
184 argv = arg_split(line, posix = not sys.platform.startswith('win'))
184 argv = arg_split(line, posix = not sys.platform.startswith('win'))
185 args, cmd = self.shebang.parser.parse_known_args(argv)
185 args, cmd = self.shebang.parser.parse_known_args(argv)
186
186
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
188
188
189 cell = cell.encode('utf8', 'replace')
189 if args.bg:
190 if args.bg:
190 if args.out:
191 if args.out:
191 self.shell.user_ns[args.out] = p.stdout
192 self.shell.user_ns[args.out] = p.stdout
192 if args.err:
193 if args.err:
193 self.shell.user_ns[args.err] = p.stderr
194 self.shell.user_ns[args.err] = p.stderr
194 self.job_manager.new(self._run_script, p, cell)
195 self.job_manager.new(self._run_script, p, cell)
195 return
196 return
196
197
197 out, err = p.communicate(cell)
198 out, err = p.communicate(cell)
198 out = py3compat.bytes_to_str(out)
199 out = py3compat.bytes_to_str(out)
199 err = py3compat.bytes_to_str(err)
200 err = py3compat.bytes_to_str(err)
200 if args.out:
201 if args.out:
201 self.shell.user_ns[args.out] = out
202 self.shell.user_ns[args.out] = out
202 else:
203 else:
203 sys.stdout.write(out)
204 sys.stdout.write(out)
204 sys.stdout.flush()
205 sys.stdout.flush()
205 if args.err:
206 if args.err:
206 self.shell.user_ns[args.err] = err
207 self.shell.user_ns[args.err] = err
207 else:
208 else:
208 sys.stderr.write(err)
209 sys.stderr.write(err)
209 sys.stderr.flush()
210 sys.stderr.flush()
210
211
211 def _run_script(self, p, cell):
212 def _run_script(self, p, cell):
212 """callback for running the script in the background"""
213 """callback for running the script in the background"""
213 p.stdin.write(cell)
214 p.stdin.write(cell)
214 p.stdin.close()
215 p.stdin.close()
215 p.wait()
216 p.wait()
@@ -1,664 +1,664 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for various magic functions.
2 """Tests for various magic functions.
3
3
4 Needs to be run by nose (to make ipython session available).
4 Needs to be run by nose (to make ipython session available).
5 """
5 """
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Imports
9 # Imports
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 import io
12 import io
13 import os
13 import os
14 import sys
14 import sys
15 from StringIO import StringIO
15 from StringIO import StringIO
16 from unittest import TestCase
16 from unittest import TestCase
17
17
18 try:
18 try:
19 from importlib import invalidate_caches # Required from Python 3.3
19 from importlib import invalidate_caches # Required from Python 3.3
20 except ImportError:
20 except ImportError:
21 def invalidate_caches():
21 def invalidate_caches():
22 pass
22 pass
23
23
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 from IPython.core import magic
26 from IPython.core import magic
27 from IPython.core.magic import (Magics, magics_class, line_magic,
27 from IPython.core.magic import (Magics, magics_class, line_magic,
28 cell_magic, line_cell_magic,
28 cell_magic, line_cell_magic,
29 register_line_magic, register_cell_magic,
29 register_line_magic, register_cell_magic,
30 register_line_cell_magic)
30 register_line_cell_magic)
31 from IPython.core.magics import execution, script
31 from IPython.core.magics import execution, script
32 from IPython.nbformat.v3.tests.nbexamples import nb0
32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 from IPython.nbformat import current
33 from IPython.nbformat import current
34 from IPython.testing import decorators as dec
34 from IPython.testing import decorators as dec
35 from IPython.testing import tools as tt
35 from IPython.testing import tools as tt
36 from IPython.utils import py3compat
36 from IPython.utils import py3compat
37 from IPython.utils.tempdir import TemporaryDirectory
37 from IPython.utils.tempdir import TemporaryDirectory
38 from IPython.utils.process import find_cmd
38 from IPython.utils.process import find_cmd
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Test functions begin
41 # Test functions begin
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 @magic.magics_class
44 @magic.magics_class
45 class DummyMagics(magic.Magics): pass
45 class DummyMagics(magic.Magics): pass
46
46
47 def test_rehashx():
47 def test_rehashx():
48 # clear up everything
48 # clear up everything
49 _ip = get_ipython()
49 _ip = get_ipython()
50 _ip.alias_manager.alias_table.clear()
50 _ip.alias_manager.alias_table.clear()
51 del _ip.db['syscmdlist']
51 del _ip.db['syscmdlist']
52
52
53 _ip.magic('rehashx')
53 _ip.magic('rehashx')
54 # Practically ALL ipython development systems will have more than 10 aliases
54 # Practically ALL ipython development systems will have more than 10 aliases
55
55
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
57 for key, val in _ip.alias_manager.alias_table.iteritems():
57 for key, val in _ip.alias_manager.alias_table.iteritems():
58 # we must strip dots from alias names
58 # we must strip dots from alias names
59 nt.assert_true('.' not in key)
59 nt.assert_true('.' not in key)
60
60
61 # rehashx must fill up syscmdlist
61 # rehashx must fill up syscmdlist
62 scoms = _ip.db['syscmdlist']
62 scoms = _ip.db['syscmdlist']
63 yield (nt.assert_true, len(scoms) > 10)
63 yield (nt.assert_true, len(scoms) > 10)
64
64
65
65
66 def test_magic_parse_options():
66 def test_magic_parse_options():
67 """Test that we don't mangle paths when parsing magic options."""
67 """Test that we don't mangle paths when parsing magic options."""
68 ip = get_ipython()
68 ip = get_ipython()
69 path = 'c:\\x'
69 path = 'c:\\x'
70 m = DummyMagics(ip)
70 m = DummyMagics(ip)
71 opts = m.parse_options('-f %s' % path,'f:')[0]
71 opts = m.parse_options('-f %s' % path,'f:')[0]
72 # argv splitting is os-dependent
72 # argv splitting is os-dependent
73 if os.name == 'posix':
73 if os.name == 'posix':
74 expected = 'c:x'
74 expected = 'c:x'
75 else:
75 else:
76 expected = path
76 expected = path
77 nt.assert_equals(opts['f'], expected)
77 nt.assert_equals(opts['f'], expected)
78
78
79 def test_magic_parse_long_options():
79 def test_magic_parse_long_options():
80 """Magic.parse_options can handle --foo=bar long options"""
80 """Magic.parse_options can handle --foo=bar long options"""
81 ip = get_ipython()
81 ip = get_ipython()
82 m = DummyMagics(ip)
82 m = DummyMagics(ip)
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
84 nt.assert_true('foo' in opts)
84 nt.assert_true('foo' in opts)
85 nt.assert_true('bar' in opts)
85 nt.assert_true('bar' in opts)
86 nt.assert_true(opts['bar'], "bubble")
86 nt.assert_true(opts['bar'], "bubble")
87
87
88
88
89 @dec.skip_without('sqlite3')
89 @dec.skip_without('sqlite3')
90 def doctest_hist_f():
90 def doctest_hist_f():
91 """Test %hist -f with temporary filename.
91 """Test %hist -f with temporary filename.
92
92
93 In [9]: import tempfile
93 In [9]: import tempfile
94
94
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
96
96
97 In [11]: %hist -nl -f $tfile 3
97 In [11]: %hist -nl -f $tfile 3
98
98
99 In [13]: import os; os.unlink(tfile)
99 In [13]: import os; os.unlink(tfile)
100 """
100 """
101
101
102
102
103 @dec.skip_without('sqlite3')
103 @dec.skip_without('sqlite3')
104 def doctest_hist_r():
104 def doctest_hist_r():
105 """Test %hist -r
105 """Test %hist -r
106
106
107 XXX - This test is not recording the output correctly. For some reason, in
107 XXX - This test is not recording the output correctly. For some reason, in
108 testing mode the raw history isn't getting populated. No idea why.
108 testing mode the raw history isn't getting populated. No idea why.
109 Disabling the output checking for now, though at least we do run it.
109 Disabling the output checking for now, though at least we do run it.
110
110
111 In [1]: 'hist' in _ip.lsmagic()
111 In [1]: 'hist' in _ip.lsmagic()
112 Out[1]: True
112 Out[1]: True
113
113
114 In [2]: x=1
114 In [2]: x=1
115
115
116 In [3]: %hist -rl 2
116 In [3]: %hist -rl 2
117 x=1 # random
117 x=1 # random
118 %hist -r 2
118 %hist -r 2
119 """
119 """
120
120
121
121
122 @dec.skip_without('sqlite3')
122 @dec.skip_without('sqlite3')
123 def doctest_hist_op():
123 def doctest_hist_op():
124 """Test %hist -op
124 """Test %hist -op
125
125
126 In [1]: class b(float):
126 In [1]: class b(float):
127 ...: pass
127 ...: pass
128 ...:
128 ...:
129
129
130 In [2]: class s(object):
130 In [2]: class s(object):
131 ...: def __str__(self):
131 ...: def __str__(self):
132 ...: return 's'
132 ...: return 's'
133 ...:
133 ...:
134
134
135 In [3]:
135 In [3]:
136
136
137 In [4]: class r(b):
137 In [4]: class r(b):
138 ...: def __repr__(self):
138 ...: def __repr__(self):
139 ...: return 'r'
139 ...: return 'r'
140 ...:
140 ...:
141
141
142 In [5]: class sr(s,r): pass
142 In [5]: class sr(s,r): pass
143 ...:
143 ...:
144
144
145 In [6]:
145 In [6]:
146
146
147 In [7]: bb=b()
147 In [7]: bb=b()
148
148
149 In [8]: ss=s()
149 In [8]: ss=s()
150
150
151 In [9]: rr=r()
151 In [9]: rr=r()
152
152
153 In [10]: ssrr=sr()
153 In [10]: ssrr=sr()
154
154
155 In [11]: 4.5
155 In [11]: 4.5
156 Out[11]: 4.5
156 Out[11]: 4.5
157
157
158 In [12]: str(ss)
158 In [12]: str(ss)
159 Out[12]: 's'
159 Out[12]: 's'
160
160
161 In [13]:
161 In [13]:
162
162
163 In [14]: %hist -op
163 In [14]: %hist -op
164 >>> class b:
164 >>> class b:
165 ... pass
165 ... pass
166 ...
166 ...
167 >>> class s(b):
167 >>> class s(b):
168 ... def __str__(self):
168 ... def __str__(self):
169 ... return 's'
169 ... return 's'
170 ...
170 ...
171 >>>
171 >>>
172 >>> class r(b):
172 >>> class r(b):
173 ... def __repr__(self):
173 ... def __repr__(self):
174 ... return 'r'
174 ... return 'r'
175 ...
175 ...
176 >>> class sr(s,r): pass
176 >>> class sr(s,r): pass
177 >>>
177 >>>
178 >>> bb=b()
178 >>> bb=b()
179 >>> ss=s()
179 >>> ss=s()
180 >>> rr=r()
180 >>> rr=r()
181 >>> ssrr=sr()
181 >>> ssrr=sr()
182 >>> 4.5
182 >>> 4.5
183 4.5
183 4.5
184 >>> str(ss)
184 >>> str(ss)
185 's'
185 's'
186 >>>
186 >>>
187 """
187 """
188
188
189
189
190 @dec.skip_without('sqlite3')
190 @dec.skip_without('sqlite3')
191 def test_macro():
191 def test_macro():
192 ip = get_ipython()
192 ip = get_ipython()
193 ip.history_manager.reset() # Clear any existing history.
193 ip.history_manager.reset() # Clear any existing history.
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
195 for i, cmd in enumerate(cmds, start=1):
195 for i, cmd in enumerate(cmds, start=1):
196 ip.history_manager.store_inputs(i, cmd)
196 ip.history_manager.store_inputs(i, cmd)
197 ip.magic("macro test 1-3")
197 ip.magic("macro test 1-3")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
199
199
200 # List macros.
200 # List macros.
201 assert "test" in ip.magic("macro")
201 assert "test" in ip.magic("macro")
202
202
203
203
204 @dec.skip_without('sqlite3')
204 @dec.skip_without('sqlite3')
205 def test_macro_run():
205 def test_macro_run():
206 """Test that we can run a multi-line macro successfully."""
206 """Test that we can run a multi-line macro successfully."""
207 ip = get_ipython()
207 ip = get_ipython()
208 ip.history_manager.reset()
208 ip.history_manager.reset()
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
210 "%macro test 2-3"]
210 "%macro test 2-3"]
211 for cmd in cmds:
211 for cmd in cmds:
212 ip.run_cell(cmd, store_history=True)
212 ip.run_cell(cmd, store_history=True)
213 nt.assert_equal(ip.user_ns["test"].value,
213 nt.assert_equal(ip.user_ns["test"].value,
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
215 with tt.AssertPrints("12"):
215 with tt.AssertPrints("12"):
216 ip.run_cell("test")
216 ip.run_cell("test")
217 with tt.AssertPrints("13"):
217 with tt.AssertPrints("13"):
218 ip.run_cell("test")
218 ip.run_cell("test")
219
219
220
220
221 @dec.skipif_not_numpy
221 @dec.skipif_not_numpy
222 def test_numpy_reset_array_undec():
222 def test_numpy_reset_array_undec():
223 "Test '%reset array' functionality"
223 "Test '%reset array' functionality"
224 _ip.ex('import numpy as np')
224 _ip.ex('import numpy as np')
225 _ip.ex('a = np.empty(2)')
225 _ip.ex('a = np.empty(2)')
226 yield (nt.assert_true, 'a' in _ip.user_ns)
226 yield (nt.assert_true, 'a' in _ip.user_ns)
227 _ip.magic('reset -f array')
227 _ip.magic('reset -f array')
228 yield (nt.assert_false, 'a' in _ip.user_ns)
228 yield (nt.assert_false, 'a' in _ip.user_ns)
229
229
230 def test_reset_out():
230 def test_reset_out():
231 "Test '%reset out' magic"
231 "Test '%reset out' magic"
232 _ip.run_cell("parrot = 'dead'", store_history=True)
232 _ip.run_cell("parrot = 'dead'", store_history=True)
233 # test '%reset -f out', make an Out prompt
233 # test '%reset -f out', make an Out prompt
234 _ip.run_cell("parrot", store_history=True)
234 _ip.run_cell("parrot", store_history=True)
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
236 _ip.magic('reset -f out')
236 _ip.magic('reset -f out')
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
239
239
240 def test_reset_in():
240 def test_reset_in():
241 "Test '%reset in' magic"
241 "Test '%reset in' magic"
242 # test '%reset -f in'
242 # test '%reset -f in'
243 _ip.run_cell("parrot", store_history=True)
243 _ip.run_cell("parrot", store_history=True)
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
245 _ip.magic('%reset -f in')
245 _ip.magic('%reset -f in')
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
248
248
249 def test_reset_dhist():
249 def test_reset_dhist():
250 "Test '%reset dhist' magic"
250 "Test '%reset dhist' magic"
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
253 _ip.magic('cd -')
253 _ip.magic('cd -')
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
255 _ip.magic('reset -f dhist')
255 _ip.magic('reset -f dhist')
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
258
258
259 def test_reset_in_length():
259 def test_reset_in_length():
260 "Test that '%reset in' preserves In[] length"
260 "Test that '%reset in' preserves In[] length"
261 _ip.run_cell("print 'foo'")
261 _ip.run_cell("print 'foo'")
262 _ip.run_cell("reset -f in")
262 _ip.run_cell("reset -f in")
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264
264
265 def test_time():
265 def test_time():
266 _ip.magic('time None')
266 _ip.magic('time None')
267
267
268 def test_tb_syntaxerror():
268 def test_tb_syntaxerror():
269 """test %tb after a SyntaxError"""
269 """test %tb after a SyntaxError"""
270 ip = get_ipython()
270 ip = get_ipython()
271 ip.run_cell("for")
271 ip.run_cell("for")
272
272
273 # trap and validate stdout
273 # trap and validate stdout
274 save_stdout = sys.stdout
274 save_stdout = sys.stdout
275 try:
275 try:
276 sys.stdout = StringIO()
276 sys.stdout = StringIO()
277 ip.run_cell("%tb")
277 ip.run_cell("%tb")
278 out = sys.stdout.getvalue()
278 out = sys.stdout.getvalue()
279 finally:
279 finally:
280 sys.stdout = save_stdout
280 sys.stdout = save_stdout
281 # trim output, and only check the last line
281 # trim output, and only check the last line
282 last_line = out.rstrip().splitlines()[-1].strip()
282 last_line = out.rstrip().splitlines()[-1].strip()
283 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
283 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
284
284
285
285
286 @py3compat.doctest_refactor_print
286 @py3compat.doctest_refactor_print
287 def doctest_time():
287 def doctest_time():
288 """
288 """
289 In [10]: %time None
289 In [10]: %time None
290 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
290 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
291 Wall time: 0.00 s
291 Wall time: 0.00 s
292
292
293 In [11]: def f(kmjy):
293 In [11]: def f(kmjy):
294 ....: %time print 2*kmjy
294 ....: %time print 2*kmjy
295
295
296 In [12]: f(3)
296 In [12]: f(3)
297 6
297 6
298 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
298 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
299 Wall time: 0.00 s
299 Wall time: 0.00 s
300 """
300 """
301
301
302
302
303 def test_doctest_mode():
303 def test_doctest_mode():
304 "Toggle doctest_mode twice, it should be a no-op and run without error"
304 "Toggle doctest_mode twice, it should be a no-op and run without error"
305 _ip.magic('doctest_mode')
305 _ip.magic('doctest_mode')
306 _ip.magic('doctest_mode')
306 _ip.magic('doctest_mode')
307
307
308
308
309 def test_parse_options():
309 def test_parse_options():
310 """Tests for basic options parsing in magics."""
310 """Tests for basic options parsing in magics."""
311 # These are only the most minimal of tests, more should be added later. At
311 # These are only the most minimal of tests, more should be added later. At
312 # the very least we check that basic text/unicode calls work OK.
312 # the very least we check that basic text/unicode calls work OK.
313 m = DummyMagics(_ip)
313 m = DummyMagics(_ip)
314 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
314 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
315 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
315 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
316
316
317
317
318 def test_dirops():
318 def test_dirops():
319 """Test various directory handling operations."""
319 """Test various directory handling operations."""
320 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
320 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
321 curpath = os.getcwdu
321 curpath = os.getcwdu
322 startdir = os.getcwdu()
322 startdir = os.getcwdu()
323 ipdir = os.path.realpath(_ip.ipython_dir)
323 ipdir = os.path.realpath(_ip.ipython_dir)
324 try:
324 try:
325 _ip.magic('cd "%s"' % ipdir)
325 _ip.magic('cd "%s"' % ipdir)
326 nt.assert_equal(curpath(), ipdir)
326 nt.assert_equal(curpath(), ipdir)
327 _ip.magic('cd -')
327 _ip.magic('cd -')
328 nt.assert_equal(curpath(), startdir)
328 nt.assert_equal(curpath(), startdir)
329 _ip.magic('pushd "%s"' % ipdir)
329 _ip.magic('pushd "%s"' % ipdir)
330 nt.assert_equal(curpath(), ipdir)
330 nt.assert_equal(curpath(), ipdir)
331 _ip.magic('popd')
331 _ip.magic('popd')
332 nt.assert_equal(curpath(), startdir)
332 nt.assert_equal(curpath(), startdir)
333 finally:
333 finally:
334 os.chdir(startdir)
334 os.chdir(startdir)
335
335
336
336
337 def test_xmode():
337 def test_xmode():
338 # Calling xmode three times should be a no-op
338 # Calling xmode three times should be a no-op
339 xmode = _ip.InteractiveTB.mode
339 xmode = _ip.InteractiveTB.mode
340 for i in range(3):
340 for i in range(3):
341 _ip.magic("xmode")
341 _ip.magic("xmode")
342 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
342 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
343
343
344 def test_reset_hard():
344 def test_reset_hard():
345 monitor = []
345 monitor = []
346 class A(object):
346 class A(object):
347 def __del__(self):
347 def __del__(self):
348 monitor.append(1)
348 monitor.append(1)
349 def __repr__(self):
349 def __repr__(self):
350 return "<A instance>"
350 return "<A instance>"
351
351
352 _ip.user_ns["a"] = A()
352 _ip.user_ns["a"] = A()
353 _ip.run_cell("a")
353 _ip.run_cell("a")
354
354
355 nt.assert_equal(monitor, [])
355 nt.assert_equal(monitor, [])
356 _ip.magic("reset -f")
356 _ip.magic("reset -f")
357 nt.assert_equal(monitor, [1])
357 nt.assert_equal(monitor, [1])
358
358
359 class TestXdel(tt.TempFileMixin):
359 class TestXdel(tt.TempFileMixin):
360 def test_xdel(self):
360 def test_xdel(self):
361 """Test that references from %run are cleared by xdel."""
361 """Test that references from %run are cleared by xdel."""
362 src = ("class A(object):\n"
362 src = ("class A(object):\n"
363 " monitor = []\n"
363 " monitor = []\n"
364 " def __del__(self):\n"
364 " def __del__(self):\n"
365 " self.monitor.append(1)\n"
365 " self.monitor.append(1)\n"
366 "a = A()\n")
366 "a = A()\n")
367 self.mktmp(src)
367 self.mktmp(src)
368 # %run creates some hidden references...
368 # %run creates some hidden references...
369 _ip.magic("run %s" % self.fname)
369 _ip.magic("run %s" % self.fname)
370 # ... as does the displayhook.
370 # ... as does the displayhook.
371 _ip.run_cell("a")
371 _ip.run_cell("a")
372
372
373 monitor = _ip.user_ns["A"].monitor
373 monitor = _ip.user_ns["A"].monitor
374 nt.assert_equal(monitor, [])
374 nt.assert_equal(monitor, [])
375
375
376 _ip.magic("xdel a")
376 _ip.magic("xdel a")
377
377
378 # Check that a's __del__ method has been called.
378 # Check that a's __del__ method has been called.
379 nt.assert_equal(monitor, [1])
379 nt.assert_equal(monitor, [1])
380
380
381 def doctest_who():
381 def doctest_who():
382 """doctest for %who
382 """doctest for %who
383
383
384 In [1]: %reset -f
384 In [1]: %reset -f
385
385
386 In [2]: alpha = 123
386 In [2]: alpha = 123
387
387
388 In [3]: beta = 'beta'
388 In [3]: beta = 'beta'
389
389
390 In [4]: %who int
390 In [4]: %who int
391 alpha
391 alpha
392
392
393 In [5]: %who str
393 In [5]: %who str
394 beta
394 beta
395
395
396 In [6]: %whos
396 In [6]: %whos
397 Variable Type Data/Info
397 Variable Type Data/Info
398 ----------------------------
398 ----------------------------
399 alpha int 123
399 alpha int 123
400 beta str beta
400 beta str beta
401
401
402 In [7]: %who_ls
402 In [7]: %who_ls
403 Out[7]: ['alpha', 'beta']
403 Out[7]: ['alpha', 'beta']
404 """
404 """
405
405
406 def test_whos():
406 def test_whos():
407 """Check that whos is protected against objects where repr() fails."""
407 """Check that whos is protected against objects where repr() fails."""
408 class A(object):
408 class A(object):
409 def __repr__(self):
409 def __repr__(self):
410 raise Exception()
410 raise Exception()
411 _ip.user_ns['a'] = A()
411 _ip.user_ns['a'] = A()
412 _ip.magic("whos")
412 _ip.magic("whos")
413
413
414 @py3compat.u_format
414 @py3compat.u_format
415 def doctest_precision():
415 def doctest_precision():
416 """doctest for %precision
416 """doctest for %precision
417
417
418 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
418 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
419
419
420 In [2]: %precision 5
420 In [2]: %precision 5
421 Out[2]: {u}'%.5f'
421 Out[2]: {u}'%.5f'
422
422
423 In [3]: f.float_format
423 In [3]: f.float_format
424 Out[3]: {u}'%.5f'
424 Out[3]: {u}'%.5f'
425
425
426 In [4]: %precision %e
426 In [4]: %precision %e
427 Out[4]: {u}'%e'
427 Out[4]: {u}'%e'
428
428
429 In [5]: f(3.1415927)
429 In [5]: f(3.1415927)
430 Out[5]: {u}'3.141593e+00'
430 Out[5]: {u}'3.141593e+00'
431 """
431 """
432
432
433 def test_psearch():
433 def test_psearch():
434 with tt.AssertPrints("dict.fromkeys"):
434 with tt.AssertPrints("dict.fromkeys"):
435 _ip.run_cell("dict.fr*?")
435 _ip.run_cell("dict.fr*?")
436
436
437 def test_timeit_shlex():
437 def test_timeit_shlex():
438 """test shlex issues with timeit (#1109)"""
438 """test shlex issues with timeit (#1109)"""
439 _ip.ex("def f(*a,**kw): pass")
439 _ip.ex("def f(*a,**kw): pass")
440 _ip.magic('timeit -n1 "this is a bug".count(" ")')
440 _ip.magic('timeit -n1 "this is a bug".count(" ")')
441 _ip.magic('timeit -r1 -n1 f(" ", 1)')
441 _ip.magic('timeit -r1 -n1 f(" ", 1)')
442 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
442 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
443 _ip.magic('timeit -r1 -n1 ("a " + "b")')
443 _ip.magic('timeit -r1 -n1 ("a " + "b")')
444 _ip.magic('timeit -r1 -n1 f("a " + "b")')
444 _ip.magic('timeit -r1 -n1 f("a " + "b")')
445 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
445 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
446
446
447
447
448 def test_timeit_arguments():
448 def test_timeit_arguments():
449 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
449 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
450 _ip.magic("timeit ('#')")
450 _ip.magic("timeit ('#')")
451
451
452
452
453 @dec.skipif(execution.profile is None)
453 @dec.skipif(execution.profile is None)
454 def test_prun_quotes():
454 def test_prun_quotes():
455 "Test that prun does not clobber string escapes (GH #1302)"
455 "Test that prun does not clobber string escapes (GH #1302)"
456 _ip.magic("prun -q x = '\t'")
456 _ip.magic("prun -q x = '\t'")
457 nt.assert_equal(_ip.user_ns['x'], '\t')
457 nt.assert_equal(_ip.user_ns['x'], '\t')
458
458
459 def test_extension():
459 def test_extension():
460 tmpdir = TemporaryDirectory()
460 tmpdir = TemporaryDirectory()
461 orig_ipython_dir = _ip.ipython_dir
461 orig_ipython_dir = _ip.ipython_dir
462 try:
462 try:
463 _ip.ipython_dir = tmpdir.name
463 _ip.ipython_dir = tmpdir.name
464 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
464 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
465 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
465 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
466 _ip.magic("install_ext %s" % url)
466 _ip.magic("install_ext %s" % url)
467 _ip.user_ns.pop('arq', None)
467 _ip.user_ns.pop('arq', None)
468 invalidate_caches() # Clear import caches
468 invalidate_caches() # Clear import caches
469 _ip.magic("load_ext daft_extension")
469 _ip.magic("load_ext daft_extension")
470 tt.assert_equal(_ip.user_ns['arq'], 185)
470 tt.assert_equal(_ip.user_ns['arq'], 185)
471 _ip.magic("unload_ext daft_extension")
471 _ip.magic("unload_ext daft_extension")
472 assert 'arq' not in _ip.user_ns
472 assert 'arq' not in _ip.user_ns
473 finally:
473 finally:
474 _ip.ipython_dir = orig_ipython_dir
474 _ip.ipython_dir = orig_ipython_dir
475
475
476 def test_notebook_export_json():
476 def test_notebook_export_json():
477 with TemporaryDirectory() as td:
477 with TemporaryDirectory() as td:
478 outfile = os.path.join(td, "nb.ipynb")
478 outfile = os.path.join(td, "nb.ipynb")
479 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
479 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
480 _ip.magic("notebook -e %s" % outfile)
480 _ip.magic("notebook -e %s" % outfile)
481
481
482 def test_notebook_export_py():
482 def test_notebook_export_py():
483 with TemporaryDirectory() as td:
483 with TemporaryDirectory() as td:
484 outfile = os.path.join(td, "nb.py")
484 outfile = os.path.join(td, "nb.py")
485 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
485 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
486 _ip.magic("notebook -e %s" % outfile)
486 _ip.magic("notebook -e %s" % outfile)
487
487
488 def test_notebook_reformat_py():
488 def test_notebook_reformat_py():
489 with TemporaryDirectory() as td:
489 with TemporaryDirectory() as td:
490 infile = os.path.join(td, "nb.ipynb")
490 infile = os.path.join(td, "nb.ipynb")
491 with io.open(infile, 'w', encoding='utf-8') as f:
491 with io.open(infile, 'w', encoding='utf-8') as f:
492 current.write(nb0, f, 'json')
492 current.write(nb0, f, 'json')
493
493
494 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
494 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
495 _ip.magic("notebook -f py %s" % infile)
495 _ip.magic("notebook -f py %s" % infile)
496
496
497 def test_notebook_reformat_json():
497 def test_notebook_reformat_json():
498 with TemporaryDirectory() as td:
498 with TemporaryDirectory() as td:
499 infile = os.path.join(td, "nb.py")
499 infile = os.path.join(td, "nb.py")
500 with io.open(infile, 'w', encoding='utf-8') as f:
500 with io.open(infile, 'w', encoding='utf-8') as f:
501 current.write(nb0, f, 'py')
501 current.write(nb0, f, 'py')
502
502
503 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
503 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
504 _ip.magic("notebook -f ipynb %s" % infile)
504 _ip.magic("notebook -f ipynb %s" % infile)
505 _ip.magic("notebook -f json %s" % infile)
505 _ip.magic("notebook -f json %s" % infile)
506
506
507 def test_env():
507 def test_env():
508 env = _ip.magic("env")
508 env = _ip.magic("env")
509 assert isinstance(env, dict), type(env)
509 assert isinstance(env, dict), type(env)
510
510
511
511
512 class CellMagicTestCase(TestCase):
512 class CellMagicTestCase(TestCase):
513
513
514 def check_ident(self, magic):
514 def check_ident(self, magic):
515 # Manually called, we get the result
515 # Manually called, we get the result
516 out = _ip.run_cell_magic(magic, 'a', 'b')
516 out = _ip.run_cell_magic(magic, 'a', 'b')
517 nt.assert_equals(out, ('a','b'))
517 nt.assert_equals(out, ('a','b'))
518 # Via run_cell, it goes into the user's namespace via displayhook
518 # Via run_cell, it goes into the user's namespace via displayhook
519 _ip.run_cell('%%' + magic +' c\nd')
519 _ip.run_cell('%%' + magic +' c\nd')
520 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
520 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
521
521
522 def test_cell_magic_func_deco(self):
522 def test_cell_magic_func_deco(self):
523 "Cell magic using simple decorator"
523 "Cell magic using simple decorator"
524 @register_cell_magic
524 @register_cell_magic
525 def cellm(line, cell):
525 def cellm(line, cell):
526 return line, cell
526 return line, cell
527
527
528 self.check_ident('cellm')
528 self.check_ident('cellm')
529
529
530 def test_cell_magic_reg(self):
530 def test_cell_magic_reg(self):
531 "Cell magic manually registered"
531 "Cell magic manually registered"
532 def cellm(line, cell):
532 def cellm(line, cell):
533 return line, cell
533 return line, cell
534
534
535 _ip.register_magic_function(cellm, 'cell', 'cellm2')
535 _ip.register_magic_function(cellm, 'cell', 'cellm2')
536 self.check_ident('cellm2')
536 self.check_ident('cellm2')
537
537
538 def test_cell_magic_class(self):
538 def test_cell_magic_class(self):
539 "Cell magics declared via a class"
539 "Cell magics declared via a class"
540 @magics_class
540 @magics_class
541 class MyMagics(Magics):
541 class MyMagics(Magics):
542
542
543 @cell_magic
543 @cell_magic
544 def cellm3(self, line, cell):
544 def cellm3(self, line, cell):
545 return line, cell
545 return line, cell
546
546
547 _ip.register_magics(MyMagics)
547 _ip.register_magics(MyMagics)
548 self.check_ident('cellm3')
548 self.check_ident('cellm3')
549
549
550 def test_cell_magic_class2(self):
550 def test_cell_magic_class2(self):
551 "Cell magics declared via a class, #2"
551 "Cell magics declared via a class, #2"
552 @magics_class
552 @magics_class
553 class MyMagics2(Magics):
553 class MyMagics2(Magics):
554
554
555 @cell_magic('cellm4')
555 @cell_magic('cellm4')
556 def cellm33(self, line, cell):
556 def cellm33(self, line, cell):
557 return line, cell
557 return line, cell
558
558
559 _ip.register_magics(MyMagics2)
559 _ip.register_magics(MyMagics2)
560 self.check_ident('cellm4')
560 self.check_ident('cellm4')
561 # Check that nothing is registered as 'cellm33'
561 # Check that nothing is registered as 'cellm33'
562 c33 = _ip.find_cell_magic('cellm33')
562 c33 = _ip.find_cell_magic('cellm33')
563 nt.assert_equals(c33, None)
563 nt.assert_equals(c33, None)
564
564
565 def test_file():
565 def test_file():
566 """Basic %%file"""
566 """Basic %%file"""
567 ip = get_ipython()
567 ip = get_ipython()
568 with TemporaryDirectory() as td:
568 with TemporaryDirectory() as td:
569 fname = os.path.join(td, 'file1')
569 fname = os.path.join(td, 'file1')
570 ip.run_cell_magic("file", fname, u'\n'.join([
570 ip.run_cell_magic("file", fname, u'\n'.join([
571 'line1',
571 'line1',
572 'line2',
572 'line2',
573 ]))
573 ]))
574 with open(fname) as f:
574 with open(fname) as f:
575 s = f.read()
575 s = f.read()
576 nt.assert_in('line1\n', s)
576 nt.assert_in('line1\n', s)
577 nt.assert_in('line2', s)
577 nt.assert_in('line2', s)
578
578
579 def test_file_unicode():
579 def test_file_unicode():
580 """%%file with unicode cell"""
580 """%%file with unicode cell"""
581 ip = get_ipython()
581 ip = get_ipython()
582 with TemporaryDirectory() as td:
582 with TemporaryDirectory() as td:
583 fname = os.path.join(td, 'file1')
583 fname = os.path.join(td, 'file1')
584 ip.run_cell_magic("file", fname, u'\n'.join([
584 ip.run_cell_magic("file", fname, u'\n'.join([
585 u'linΓ©1',
585 u'linΓ©1',
586 u'linΓ©2',
586 u'linΓ©2',
587 ]))
587 ]))
588 with io.open(fname, encoding='utf-8') as f:
588 with io.open(fname, encoding='utf-8') as f:
589 s = f.read()
589 s = f.read()
590 nt.assert_in(u'linΓ©1\n', s)
590 nt.assert_in(u'linΓ©1\n', s)
591 nt.assert_in(u'linΓ©2', s)
591 nt.assert_in(u'linΓ©2', s)
592
592
593 def test_file_amend():
593 def test_file_amend():
594 """%%file -a amends files"""
594 """%%file -a amends files"""
595 ip = get_ipython()
595 ip = get_ipython()
596 with TemporaryDirectory() as td:
596 with TemporaryDirectory() as td:
597 fname = os.path.join(td, 'file2')
597 fname = os.path.join(td, 'file2')
598 ip.run_cell_magic("file", fname, u'\n'.join([
598 ip.run_cell_magic("file", fname, u'\n'.join([
599 'line1',
599 'line1',
600 'line2',
600 'line2',
601 ]))
601 ]))
602 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
602 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
603 'line3',
603 'line3',
604 'line4',
604 'line4',
605 ]))
605 ]))
606 with open(fname) as f:
606 with open(fname) as f:
607 s = f.read()
607 s = f.read()
608 nt.assert_in('line1\n', s)
608 nt.assert_in('line1\n', s)
609 nt.assert_in('line3\n', s)
609 nt.assert_in('line3\n', s)
610
610
611
611
612 def test_script_config():
612 def test_script_config():
613 ip = get_ipython()
613 ip = get_ipython()
614 ip.config.ScriptMagics.script_magics = ['whoda']
614 ip.config.ScriptMagics.script_magics = ['whoda']
615 sm = script.ScriptMagics(shell=ip)
615 sm = script.ScriptMagics(shell=ip)
616 nt.assert_in('whoda', sm.magics['cell'])
616 nt.assert_in('whoda', sm.magics['cell'])
617
617
618 @dec.skip_win32
618 @dec.skip_win32
619 def test_script_out():
619 def test_script_out():
620 ip = get_ipython()
620 ip = get_ipython()
621 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
621 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
622 nt.assert_equals(ip.user_ns['output'], 'hi\n')
622 nt.assert_equals(ip.user_ns['output'], 'hi\n')
623
623
624 @dec.skip_win32
624 @dec.skip_win32
625 def test_script_err():
625 def test_script_err():
626 ip = get_ipython()
626 ip = get_ipython()
627 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
627 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
628 nt.assert_equals(ip.user_ns['error'], 'hello\n')
628 nt.assert_equals(ip.user_ns['error'], 'hello\n')
629
629
630 @dec.skip_win32
630 @dec.skip_win32
631 def test_script_out_err():
631 def test_script_out_err():
632 ip = get_ipython()
632 ip = get_ipython()
633 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
633 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
634 nt.assert_equals(ip.user_ns['output'], 'hi\n')
634 nt.assert_equals(ip.user_ns['output'], 'hi\n')
635 nt.assert_equals(ip.user_ns['error'], 'hello\n')
635 nt.assert_equals(ip.user_ns['error'], 'hello\n')
636
636
637 @dec.skip_win32
637 @dec.skip_win32
638 def test_script_bg_out():
638 def test_script_bg_out():
639 ip = get_ipython()
639 ip = get_ipython()
640 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
640 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
641 nt.assert_equals(ip.user_ns['output'].read(), 'hi\n')
641 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
642
642
643 @dec.skip_win32
643 @dec.skip_win32
644 def test_script_bg_err():
644 def test_script_bg_err():
645 ip = get_ipython()
645 ip = get_ipython()
646 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
646 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
647 nt.assert_equals(ip.user_ns['error'].read(), 'hello\n')
647 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
648
648
649 @dec.skip_win32
649 @dec.skip_win32
650 def test_script_bg_out_err():
650 def test_script_bg_out_err():
651 ip = get_ipython()
651 ip = get_ipython()
652 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
652 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
653 nt.assert_equals(ip.user_ns['output'].read(), 'hi\n')
653 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
654 nt.assert_equals(ip.user_ns['error'].read(), 'hello\n')
654 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
655
655
656 def test_script_defaults():
656 def test_script_defaults():
657 ip = get_ipython()
657 ip = get_ipython()
658 for cmd in ['sh', 'bash', 'perl', 'ruby']:
658 for cmd in ['sh', 'bash', 'perl', 'ruby']:
659 try:
659 try:
660 find_cmd(cmd)
660 find_cmd(cmd)
661 except Exception:
661 except Exception:
662 pass
662 pass
663 else:
663 else:
664 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
664 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
General Comments 0
You need to be logged in to leave comments. Login now