##// END OF EJS Templates
Fix various tests in IPython.core for Python 3.
Thomas Kluyver -
Show More
@@ -1,43 +1,45 b''
1 """These kinds of tests are less than ideal, but at least they run.
1 """These kinds of tests are less than ideal, but at least they run.
2
2
3 This was an old test that was being run interactively in the top-level tests/
3 This was an old test that was being run interactively in the top-level tests/
4 directory, which we are removing. For now putting this here ensures at least
4 directory, which we are removing. For now putting this here ensures at least
5 we do run the test, though ultimately this functionality should all be tested
5 we do run the test, though ultimately this functionality should all be tested
6 with better-isolated tests that don't rely on the global instance in iptest.
6 with better-isolated tests that don't rely on the global instance in iptest.
7 """
7 """
8 from IPython.utils import py3compat
8
9
10 @py3compat.doctest_refactor_print
9 def doctest_autocall():
11 def doctest_autocall():
10 """
12 """
11 In [1]: def f1(a,b,c):
13 In [1]: def f1(a,b,c):
12 ...: return a+b+c
14 ...: return a+b+c
13 ...:
15 ...:
14
16
15 In [2]: def f2(a):
17 In [2]: def f2(a):
16 ...: return a + a
18 ...: return a + a
17 ...:
19 ...:
18
20
19 In [3]: ;f2 a b c
21 In [3]: ;f2 a b c
20 Out[3]: 'a b ca b c'
22 Out[3]: 'a b ca b c'
21
23
22 In [4]: assert _ == "a b ca b c"
24 In [4]: assert _ == "a b ca b c"
23
25
24 In [5]: ,f1 a b c
26 In [5]: ,f1 a b c
25 Out[5]: 'abc'
27 Out[5]: 'abc'
26
28
27 In [6]: assert _ == 'abc'
29 In [6]: assert _ == 'abc'
28
30
29 In [7]: print _
31 In [7]: print _
30 abc
32 abc
31
33
32 In [8]: /f1 1,2,3
34 In [8]: /f1 1,2,3
33 Out[8]: 6
35 Out[8]: 6
34
36
35 In [9]: assert _ == 6
37 In [9]: assert _ == 6
36
38
37 In [10]: /f2 4
39 In [10]: /f2 4
38 Out[10]: 8
40 Out[10]: 8
39
41
40 In [11]: assert _ == 8
42 In [11]: assert _ == 8
41
43
42 In [11]: del f1, f2
44 In [11]: del f1, f2
43 """
45 """
@@ -1,165 +1,167 b''
1 """Tests for input handlers.
1 """Tests for input handlers.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # third party
7 # third party
8 import nose.tools as nt
8 import nose.tools as nt
9
9
10 # our own packages
10 # our own packages
11 from IPython.core import autocall
11 from IPython.core import autocall
12 from IPython.testing import decorators as dec
12 from IPython.testing import decorators as dec
13 from IPython.testing import tools as tt
13 from IPython.testing import tools as tt
14 from IPython.testing.globalipapp import get_ipython
14 from IPython.testing.globalipapp import get_ipython
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Globals
17 # Globals
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 # Get the public instance of IPython
20 # Get the public instance of IPython
21 ip = get_ipython()
21 ip = get_ipython()
22
22
23 failures = []
23 failures = []
24 num_tests = 0
24 num_tests = 0
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Test functions
27 # Test functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class CallableIndexable(object):
30 class CallableIndexable(object):
31 def __getitem__(self, idx): return True
31 def __getitem__(self, idx): return True
32 def __call__(self, *args, **kws): return True
32 def __call__(self, *args, **kws): return True
33
33
34
34
35 class Autocallable(autocall.IPyAutocall):
35 class Autocallable(autocall.IPyAutocall):
36 def __call__(self):
36 def __call__(self):
37 return "called"
37 return "called"
38
38
39
39
40 def run(tests):
40 def run(tests):
41 """Loop through a list of (pre, post) inputs, where pre is the string
41 """Loop through a list of (pre, post) inputs, where pre is the string
42 handed to ipython, and post is how that string looks after it's been
42 handed to ipython, and post is how that string looks after it's been
43 transformed (i.e. ipython's notion of _i)"""
43 transformed (i.e. ipython's notion of _i)"""
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
45
45
46
46
47 def test_handlers():
47 def test_handlers():
48 # alias expansion
48 # alias expansion
49
49
50 # We're using 'true' as our syscall of choice because it doesn't
50 # We're using 'true' as our syscall of choice because it doesn't
51 # write anything to stdout.
51 # write anything to stdout.
52
52
53 # Turn off actual execution of aliases, because it's noisy
53 # Turn off actual execution of aliases, because it's noisy
54 old_system_cmd = ip.system
54 old_system_cmd = ip.system
55 ip.system = lambda cmd: None
55 ip.system = lambda cmd: None
56
56
57
57
58 ip.alias_manager.alias_table['an_alias'] = (0, 'true')
58 ip.alias_manager.alias_table['an_alias'] = (0, 'true')
59 # These are useful for checking a particular recursive alias issue
59 # These are useful for checking a particular recursive alias issue
60 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
60 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
61 ip.alias_manager.alias_table['d'] = (0, 'true')
61 ip.alias_manager.alias_table['d'] = (0, 'true')
62 run([("an_alias", 'get_ipython().system(u"true ")'), # alias
62 run([(i,py3compat.u_format(o)) for i,o in \
63 [("an_alias", 'get_ipython().system({u}"true ")'), # alias
63 # Below: recursive aliases should expand whitespace-surrounded
64 # Below: recursive aliases should expand whitespace-surrounded
64 # chars, *not* initial chars which happen to be aliases:
65 # chars, *not* initial chars which happen to be aliases:
65 ("top", 'get_ipython().system(u"d:/cygwin/top ")'),
66 ("top", 'get_ipython().system({u}"d:/cygwin/top ")'),
66 ])
67 ]])
67 ip.system = old_system_cmd
68 ip.system = old_system_cmd
68
69
69 call_idx = CallableIndexable()
70 call_idx = CallableIndexable()
70 ip.user_ns['call_idx'] = call_idx
71 ip.user_ns['call_idx'] = call_idx
71
72
72 # For many of the below, we're also checking that leading whitespace
73 # For many of the below, we're also checking that leading whitespace
73 # turns off the esc char, which it should unless there is a continuation
74 # turns off the esc char, which it should unless there is a continuation
74 # line.
75 # line.
75 run([('"no change"', '"no change"'), # normal
76 run([(i,py3compat.u_format(o)) for i,o in \
76 ("!true", 'get_ipython().system(u"true")'), # shell_escapes
77 [('"no change"', '"no change"'), # normal
77 ("!! true", 'get_ipython().magic(u"sx true")'), # shell_escapes + magic
78 ("!true", 'get_ipython().system({u}"true")'), # shell_escapes
78 ("!!true", 'get_ipython().magic(u"sx true")'), # shell_escapes + magic
79 ("!! true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
79 ("%lsmagic", 'get_ipython().magic(u"lsmagic ")'), # magic
80 ("!!true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
80 ("lsmagic", 'get_ipython().magic(u"lsmagic ")'), # magic
81 ("%lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
82 ("lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
81 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
83 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
82
84
83 # post-esc-char whitespace goes inside
85 # post-esc-char whitespace goes inside
84 ("! true", 'get_ipython().system(u" true")'),
86 ("! true", 'get_ipython().system({u}" true")'),
85
87
86 # handle_help
88 # handle_help
87
89
88 # These are weak tests -- just looking at what the help handlers
90 # These are weak tests -- just looking at what the help handlers
89 # logs, which is not how it really does its work. But it still
91 # logs, which is not how it really does its work. But it still
90 # lets us check the key paths through the handler.
92 # lets us check the key paths through the handler.
91
93
92 ("x=1 # what?", "x=1 # what?"), # no help if valid python
94 ("x=1 # what?", "x=1 # what?"), # no help if valid python
93 ])
95 ]])
94
96
95 # multi_line_specials
97 # multi_line_specials
96 ip.prefilter_manager.multi_line_specials = False
98 ip.prefilter_manager.multi_line_specials = False
97 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
99 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
98 run([
100 run([
99 ('if 1:\n !true', 'if 1:\n !true'),
101 ('if 1:\n !true', 'if 1:\n !true'),
100 ('if 1:\n lsmagic', 'if 1:\n lsmagic'),
102 ('if 1:\n lsmagic', 'if 1:\n lsmagic'),
101 ('if 1:\n an_alias', 'if 1:\n an_alias'),
103 ('if 1:\n an_alias', 'if 1:\n an_alias'),
102 ])
104 ])
103
105
104 ip.prefilter_manager.multi_line_specials = True
106 ip.prefilter_manager.multi_line_specials = True
105 # initial indents must be preserved.
107 # initial indents must be preserved.
106 run([
108 run([(i,py3compat.u_format(o)) for i,o in \
107 ('if 1:\n !true', 'if 1:\n get_ipython().system(u"true")'),
109 [('if 1:\n !true', 'if 1:\n get_ipython().system({u}"true")'),
108 ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic(u"lsmagic ")'),
110 ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic({u}"lsmagic ")'),
109 ('if 1:\n an_alias', 'if 1:\n get_ipython().system(u"true ")'),
111 ('if 1:\n an_alias', 'if 1:\n get_ipython().system({u}"true ")'),
110 # Weird one
112 # Weird one
111 ('if 1:\n !!true', 'if 1:\n get_ipython().magic(u"sx true")'),
113 ('if 1:\n !!true', 'if 1:\n get_ipython().magic({u}"sx true")'),
112
114
113 # Even with m_l_s on, autocall is off even with special chars
115 # Even with m_l_s on, autocall is off even with special chars
114 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
116 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
115 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
117 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
116 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
118 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
117 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
119 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
118 # What about !!
120 # What about !!
119 ])
121 ]])
120
122
121 # Objects which are instances of IPyAutocall are *always* autocalled
123 # Objects which are instances of IPyAutocall are *always* autocalled
122 autocallable = Autocallable()
124 autocallable = Autocallable()
123 ip.user_ns['autocallable'] = autocallable
125 ip.user_ns['autocallable'] = autocallable
124
126
125 # auto
127 # auto
126 ip.magic('autocall 0')
128 ip.magic('autocall 0')
127 # Only explicit escapes or instances of IPyAutocallable should get
129 # Only explicit escapes or instances of IPyAutocallable should get
128 # expanded
130 # expanded
129 run([
131 run([
130 ('len "abc"', 'len "abc"'),
132 ('len "abc"', 'len "abc"'),
131 ('autocallable', 'autocallable()'),
133 ('autocallable', 'autocallable()'),
132 (",list 1 2 3", 'list("1", "2", "3")'),
134 (",list 1 2 3", 'list("1", "2", "3")'),
133 (";list 1 2 3", 'list("1 2 3")'),
135 (";list 1 2 3", 'list("1 2 3")'),
134 ("/len range(1,4)", 'len(range(1,4))'),
136 ("/len range(1,4)", 'len(range(1,4))'),
135 ])
137 ])
136 ip.magic('autocall 1')
138 ip.magic('autocall 1')
137 run([
139 run([
138 (",list 1 2 3", 'list("1", "2", "3")'),
140 (",list 1 2 3", 'list("1", "2", "3")'),
139 (";list 1 2 3", 'list("1 2 3")'),
141 (";list 1 2 3", 'list("1 2 3")'),
140 ("/len range(1,4)", 'len(range(1,4))'),
142 ("/len range(1,4)", 'len(range(1,4))'),
141 ('len "abc"', 'len("abc")'),
143 ('len "abc"', 'len("abc")'),
142 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
144 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
143 # Autocall is turned off if first arg is [] and the object
145 # Autocall is turned off if first arg is [] and the object
144 # is both callable and indexable. Like so:
146 # is both callable and indexable. Like so:
145 ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
147 ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
146 ('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
148 ('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
147 ('call_idx 1', 'call_idx(1)'),
149 ('call_idx 1', 'call_idx(1)'),
148 ('len', 'len '), # only at 2 does it auto-call on single args
150 ('len', 'len '), # only at 2 does it auto-call on single args
149 ])
151 ])
150 ip.magic('autocall 2')
152 ip.magic('autocall 2')
151 run([
153 run([
152 (",list 1 2 3", 'list("1", "2", "3")'),
154 (",list 1 2 3", 'list("1", "2", "3")'),
153 (";list 1 2 3", 'list("1 2 3")'),
155 (";list 1 2 3", 'list("1 2 3")'),
154 ("/len range(1,4)", 'len(range(1,4))'),
156 ("/len range(1,4)", 'len(range(1,4))'),
155 ('len "abc"', 'len("abc")'),
157 ('len "abc"', 'len("abc")'),
156 ('len "abc";', 'len("abc");'),
158 ('len "abc";', 'len("abc");'),
157 ('len [1,2]', 'len([1,2])'),
159 ('len [1,2]', 'len([1,2])'),
158 ('call_idx [1]', 'call_idx [1]'),
160 ('call_idx [1]', 'call_idx [1]'),
159 ('call_idx 1', 'call_idx(1)'),
161 ('call_idx 1', 'call_idx(1)'),
160 # This is what's different:
162 # This is what's different:
161 ('len', 'len()'), # only at 2 does it auto-call on single args
163 ('len', 'len()'), # only at 2 does it auto-call on single args
162 ])
164 ])
163 ip.magic('autocall 1')
165 ip.magic('autocall 1')
164
166
165 nt.assert_equals(failures, [])
167 nt.assert_equals(failures, [])
@@ -1,690 +1,698 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the inputsplitter module.
2 """Tests for the inputsplitter module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Fernando Perez
6 * Fernando Perez
7 * Robert Kern
7 * Robert Kern
8 """
8 """
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010 The IPython Development Team
10 # Copyright (C) 2010 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # stdlib
19 # stdlib
20 import unittest
20 import unittest
21 import sys
21 import sys
22
22
23 # Third party
23 # Third party
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 # Our own
26 # Our own
27 from IPython.core import inputsplitter as isp
27 from IPython.core import inputsplitter as isp
28 from IPython.testing import tools as tt
28 from IPython.testing import tools as tt
29 from IPython.utils import py3compat
29
30
30 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
31 # Semi-complete examples (also used as tests)
32 # Semi-complete examples (also used as tests)
32 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
33
34
34 # Note: at the bottom, there's a slightly more complete version of this that
35 # Note: at the bottom, there's a slightly more complete version of this that
35 # can be useful during development of code here.
36 # can be useful during development of code here.
36
37
37 def mini_interactive_loop(input_func):
38 def mini_interactive_loop(input_func):
38 """Minimal example of the logic of an interactive interpreter loop.
39 """Minimal example of the logic of an interactive interpreter loop.
39
40
40 This serves as an example, and it is used by the test system with a fake
41 This serves as an example, and it is used by the test system with a fake
41 raw_input that simulates interactive input."""
42 raw_input that simulates interactive input."""
42
43
43 from IPython.core.inputsplitter import InputSplitter
44 from IPython.core.inputsplitter import InputSplitter
44
45
45 isp = InputSplitter()
46 isp = InputSplitter()
46 # In practice, this input loop would be wrapped in an outside loop to read
47 # In practice, this input loop would be wrapped in an outside loop to read
47 # input indefinitely, until some exit/quit command was issued. Here we
48 # input indefinitely, until some exit/quit command was issued. Here we
48 # only illustrate the basic inner loop.
49 # only illustrate the basic inner loop.
49 while isp.push_accepts_more():
50 while isp.push_accepts_more():
50 indent = ' '*isp.indent_spaces
51 indent = ' '*isp.indent_spaces
51 prompt = '>>> ' + indent
52 prompt = '>>> ' + indent
52 line = indent + input_func(prompt)
53 line = indent + input_func(prompt)
53 isp.push(line)
54 isp.push(line)
54
55
55 # Here we just return input so we can use it in a test suite, but a real
56 # Here we just return input so we can use it in a test suite, but a real
56 # interpreter would instead send it for execution somewhere.
57 # interpreter would instead send it for execution somewhere.
57 src = isp.source_reset()
58 src = isp.source_reset()
58 #print 'Input source was:\n', src # dbg
59 #print 'Input source was:\n', src # dbg
59 return src
60 return src
60
61
61 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
62 # Test utilities, just for local use
63 # Test utilities, just for local use
63 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
64
65
65 def assemble(block):
66 def assemble(block):
66 """Assemble a block into multi-line sub-blocks."""
67 """Assemble a block into multi-line sub-blocks."""
67 return ['\n'.join(sub_block)+'\n' for sub_block in block]
68 return ['\n'.join(sub_block)+'\n' for sub_block in block]
68
69
69
70
70 def pseudo_input(lines):
71 def pseudo_input(lines):
71 """Return a function that acts like raw_input but feeds the input list."""
72 """Return a function that acts like raw_input but feeds the input list."""
72 ilines = iter(lines)
73 ilines = iter(lines)
73 def raw_in(prompt):
74 def raw_in(prompt):
74 try:
75 try:
75 return next(ilines)
76 return next(ilines)
76 except StopIteration:
77 except StopIteration:
77 return ''
78 return ''
78 return raw_in
79 return raw_in
79
80
80 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
81 # Tests
82 # Tests
82 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
83 def test_spaces():
84 def test_spaces():
84 tests = [('', 0),
85 tests = [('', 0),
85 (' ', 1),
86 (' ', 1),
86 ('\n', 0),
87 ('\n', 0),
87 (' \n', 1),
88 (' \n', 1),
88 ('x', 0),
89 ('x', 0),
89 (' x', 1),
90 (' x', 1),
90 (' x',2),
91 (' x',2),
91 (' x',4),
92 (' x',4),
92 # Note: tabs are counted as a single whitespace!
93 # Note: tabs are counted as a single whitespace!
93 ('\tx', 1),
94 ('\tx', 1),
94 ('\t x', 2),
95 ('\t x', 2),
95 ]
96 ]
96 tt.check_pairs(isp.num_ini_spaces, tests)
97 tt.check_pairs(isp.num_ini_spaces, tests)
97
98
98
99
99 def test_remove_comments():
100 def test_remove_comments():
100 tests = [('text', 'text'),
101 tests = [('text', 'text'),
101 ('text # comment', 'text '),
102 ('text # comment', 'text '),
102 ('text # comment\n', 'text \n'),
103 ('text # comment\n', 'text \n'),
103 ('text # comment \n', 'text \n'),
104 ('text # comment \n', 'text \n'),
104 ('line # c \nline\n','line \nline\n'),
105 ('line # c \nline\n','line \nline\n'),
105 ('line # c \nline#c2 \nline\nline #c\n\n',
106 ('line # c \nline#c2 \nline\nline #c\n\n',
106 'line \nline\nline\nline \n\n'),
107 'line \nline\nline\nline \n\n'),
107 ]
108 ]
108 tt.check_pairs(isp.remove_comments, tests)
109 tt.check_pairs(isp.remove_comments, tests)
109
110
110 def test_has_comment():
111 def test_has_comment():
111 tests = [('text', False),
112 tests = [('text', False),
112 ('text #comment', True),
113 ('text #comment', True),
113 ('text #comment\n', True),
114 ('text #comment\n', True),
114 ('#comment', True),
115 ('#comment', True),
115 ('#comment\n', True),
116 ('#comment\n', True),
116 ('a = "#string"', False),
117 ('a = "#string"', False),
117 ('a = "#string" # comment', True),
118 ('a = "#string" # comment', True),
118 ('a #comment not "string"', True),
119 ('a #comment not "string"', True),
119 ]
120 ]
120 tt.check_pairs(isp.has_comment, tests)
121 tt.check_pairs(isp.has_comment, tests)
121
122
122
123
123 def test_get_input_encoding():
124 def test_get_input_encoding():
124 encoding = isp.get_input_encoding()
125 encoding = isp.get_input_encoding()
125 nt.assert_true(isinstance(encoding, basestring))
126 nt.assert_true(isinstance(encoding, basestring))
126 # simple-minded check that at least encoding a simple string works with the
127 # simple-minded check that at least encoding a simple string works with the
127 # encoding we got.
128 # encoding we got.
128 nt.assert_equal(u'test'.encode(encoding), b'test')
129 nt.assert_equal(u'test'.encode(encoding), b'test')
129
130
130
131
131 class NoInputEncodingTestCase(unittest.TestCase):
132 class NoInputEncodingTestCase(unittest.TestCase):
132 def setUp(self):
133 def setUp(self):
133 self.old_stdin = sys.stdin
134 self.old_stdin = sys.stdin
134 class X: pass
135 class X: pass
135 fake_stdin = X()
136 fake_stdin = X()
136 sys.stdin = fake_stdin
137 sys.stdin = fake_stdin
137
138
138 def test(self):
139 def test(self):
139 # Verify that if sys.stdin has no 'encoding' attribute we do the right
140 # Verify that if sys.stdin has no 'encoding' attribute we do the right
140 # thing
141 # thing
141 enc = isp.get_input_encoding()
142 enc = isp.get_input_encoding()
142 self.assertEqual(enc, 'ascii')
143 self.assertEqual(enc, 'ascii')
143
144
144 def tearDown(self):
145 def tearDown(self):
145 sys.stdin = self.old_stdin
146 sys.stdin = self.old_stdin
146
147
147
148
148 class InputSplitterTestCase(unittest.TestCase):
149 class InputSplitterTestCase(unittest.TestCase):
149 def setUp(self):
150 def setUp(self):
150 self.isp = isp.InputSplitter()
151 self.isp = isp.InputSplitter()
151
152
152 def test_reset(self):
153 def test_reset(self):
153 isp = self.isp
154 isp = self.isp
154 isp.push('x=1')
155 isp.push('x=1')
155 isp.reset()
156 isp.reset()
156 self.assertEqual(isp._buffer, [])
157 self.assertEqual(isp._buffer, [])
157 self.assertEqual(isp.indent_spaces, 0)
158 self.assertEqual(isp.indent_spaces, 0)
158 self.assertEqual(isp.source, '')
159 self.assertEqual(isp.source, '')
159 self.assertEqual(isp.code, None)
160 self.assertEqual(isp.code, None)
160 self.assertEqual(isp._is_complete, False)
161 self.assertEqual(isp._is_complete, False)
161
162
162 def test_source(self):
163 def test_source(self):
163 self.isp._store('1')
164 self.isp._store('1')
164 self.isp._store('2')
165 self.isp._store('2')
165 self.assertEqual(self.isp.source, '1\n2\n')
166 self.assertEqual(self.isp.source, '1\n2\n')
166 self.assertTrue(len(self.isp._buffer)>0)
167 self.assertTrue(len(self.isp._buffer)>0)
167 self.assertEqual(self.isp.source_reset(), '1\n2\n')
168 self.assertEqual(self.isp.source_reset(), '1\n2\n')
168 self.assertEqual(self.isp._buffer, [])
169 self.assertEqual(self.isp._buffer, [])
169 self.assertEqual(self.isp.source, '')
170 self.assertEqual(self.isp.source, '')
170
171
171 def test_indent(self):
172 def test_indent(self):
172 isp = self.isp # shorthand
173 isp = self.isp # shorthand
173 isp.push('x=1')
174 isp.push('x=1')
174 self.assertEqual(isp.indent_spaces, 0)
175 self.assertEqual(isp.indent_spaces, 0)
175 isp.push('if 1:\n x=1')
176 isp.push('if 1:\n x=1')
176 self.assertEqual(isp.indent_spaces, 4)
177 self.assertEqual(isp.indent_spaces, 4)
177 isp.push('y=2\n')
178 isp.push('y=2\n')
178 self.assertEqual(isp.indent_spaces, 0)
179 self.assertEqual(isp.indent_spaces, 0)
179
180
180 def test_indent2(self):
181 def test_indent2(self):
181 # In cell mode, inputs must be fed in whole blocks, so skip this test
182 # In cell mode, inputs must be fed in whole blocks, so skip this test
182 if self.isp.input_mode == 'cell': return
183 if self.isp.input_mode == 'cell': return
183
184
184 isp = self.isp
185 isp = self.isp
185 isp.push('if 1:')
186 isp.push('if 1:')
186 self.assertEqual(isp.indent_spaces, 4)
187 self.assertEqual(isp.indent_spaces, 4)
187 isp.push(' x=1')
188 isp.push(' x=1')
188 self.assertEqual(isp.indent_spaces, 4)
189 self.assertEqual(isp.indent_spaces, 4)
189 # Blank lines shouldn't change the indent level
190 # Blank lines shouldn't change the indent level
190 isp.push(' '*2)
191 isp.push(' '*2)
191 self.assertEqual(isp.indent_spaces, 4)
192 self.assertEqual(isp.indent_spaces, 4)
192
193
193 def test_indent3(self):
194 def test_indent3(self):
194 # In cell mode, inputs must be fed in whole blocks, so skip this test
195 # In cell mode, inputs must be fed in whole blocks, so skip this test
195 if self.isp.input_mode == 'cell': return
196 if self.isp.input_mode == 'cell': return
196
197
197 isp = self.isp
198 isp = self.isp
198 # When a multiline statement contains parens or multiline strings, we
199 # When a multiline statement contains parens or multiline strings, we
199 # shouldn't get confused.
200 # shouldn't get confused.
200 isp.push("if 1:")
201 isp.push("if 1:")
201 isp.push(" x = (1+\n 2)")
202 isp.push(" x = (1+\n 2)")
202 self.assertEqual(isp.indent_spaces, 4)
203 self.assertEqual(isp.indent_spaces, 4)
203
204
204 def test_indent4(self):
205 def test_indent4(self):
205 # In cell mode, inputs must be fed in whole blocks, so skip this test
206 # In cell mode, inputs must be fed in whole blocks, so skip this test
206 if self.isp.input_mode == 'cell': return
207 if self.isp.input_mode == 'cell': return
207
208
208 isp = self.isp
209 isp = self.isp
209 # whitespace after ':' should not screw up indent level
210 # whitespace after ':' should not screw up indent level
210 isp.push('if 1: \n x=1')
211 isp.push('if 1: \n x=1')
211 self.assertEqual(isp.indent_spaces, 4)
212 self.assertEqual(isp.indent_spaces, 4)
212 isp.push('y=2\n')
213 isp.push('y=2\n')
213 self.assertEqual(isp.indent_spaces, 0)
214 self.assertEqual(isp.indent_spaces, 0)
214 isp.push('if 1:\t\n x=1')
215 isp.push('if 1:\t\n x=1')
215 self.assertEqual(isp.indent_spaces, 4)
216 self.assertEqual(isp.indent_spaces, 4)
216 isp.push('y=2\n')
217 isp.push('y=2\n')
217 self.assertEqual(isp.indent_spaces, 0)
218 self.assertEqual(isp.indent_spaces, 0)
218
219
219 def test_dedent_pass(self):
220 def test_dedent_pass(self):
220 isp = self.isp # shorthand
221 isp = self.isp # shorthand
221 # should NOT cause dedent
222 # should NOT cause dedent
222 isp.push('if 1:\n passes = 5')
223 isp.push('if 1:\n passes = 5')
223 self.assertEqual(isp.indent_spaces, 4)
224 self.assertEqual(isp.indent_spaces, 4)
224 isp.push('if 1:\n pass')
225 isp.push('if 1:\n pass')
225 self.assertEqual(isp.indent_spaces, 0)
226 self.assertEqual(isp.indent_spaces, 0)
226 isp.push('if 1:\n pass ')
227 isp.push('if 1:\n pass ')
227 self.assertEqual(isp.indent_spaces, 0)
228 self.assertEqual(isp.indent_spaces, 0)
228
229
229 def test_dedent_raise(self):
230 def test_dedent_raise(self):
230 isp = self.isp # shorthand
231 isp = self.isp # shorthand
231 # should NOT cause dedent
232 # should NOT cause dedent
232 isp.push('if 1:\n raised = 4')
233 isp.push('if 1:\n raised = 4')
233 self.assertEqual(isp.indent_spaces, 4)
234 self.assertEqual(isp.indent_spaces, 4)
234 isp.push('if 1:\n raise TypeError()')
235 isp.push('if 1:\n raise TypeError()')
235 self.assertEqual(isp.indent_spaces, 0)
236 self.assertEqual(isp.indent_spaces, 0)
236 isp.push('if 1:\n raise')
237 isp.push('if 1:\n raise')
237 self.assertEqual(isp.indent_spaces, 0)
238 self.assertEqual(isp.indent_spaces, 0)
238 isp.push('if 1:\n raise ')
239 isp.push('if 1:\n raise ')
239 self.assertEqual(isp.indent_spaces, 0)
240 self.assertEqual(isp.indent_spaces, 0)
240
241
241 def test_dedent_return(self):
242 def test_dedent_return(self):
242 isp = self.isp # shorthand
243 isp = self.isp # shorthand
243 # should NOT cause dedent
244 # should NOT cause dedent
244 isp.push('if 1:\n returning = 4')
245 isp.push('if 1:\n returning = 4')
245 self.assertEqual(isp.indent_spaces, 4)
246 self.assertEqual(isp.indent_spaces, 4)
246 isp.push('if 1:\n return 5 + 493')
247 isp.push('if 1:\n return 5 + 493')
247 self.assertEqual(isp.indent_spaces, 0)
248 self.assertEqual(isp.indent_spaces, 0)
248 isp.push('if 1:\n return')
249 isp.push('if 1:\n return')
249 self.assertEqual(isp.indent_spaces, 0)
250 self.assertEqual(isp.indent_spaces, 0)
250 isp.push('if 1:\n return ')
251 isp.push('if 1:\n return ')
251 self.assertEqual(isp.indent_spaces, 0)
252 self.assertEqual(isp.indent_spaces, 0)
252 isp.push('if 1:\n return(0)')
253 isp.push('if 1:\n return(0)')
253 self.assertEqual(isp.indent_spaces, 0)
254 self.assertEqual(isp.indent_spaces, 0)
254
255
255 def test_push(self):
256 def test_push(self):
256 isp = self.isp
257 isp = self.isp
257 self.assertTrue(isp.push('x=1'))
258 self.assertTrue(isp.push('x=1'))
258
259
259 def test_push2(self):
260 def test_push2(self):
260 isp = self.isp
261 isp = self.isp
261 self.assertFalse(isp.push('if 1:'))
262 self.assertFalse(isp.push('if 1:'))
262 for line in [' x=1', '# a comment', ' y=2']:
263 for line in [' x=1', '# a comment', ' y=2']:
263 self.assertTrue(isp.push(line))
264 self.assertTrue(isp.push(line))
264
265
265 def test_push3(self):
266 def test_push3(self):
266 isp = self.isp
267 isp = self.isp
267 isp.push('if True:')
268 isp.push('if True:')
268 isp.push(' a = 1')
269 isp.push(' a = 1')
269 self.assertFalse(isp.push('b = [1,'))
270 self.assertFalse(isp.push('b = [1,'))
270
271
271 def test_replace_mode(self):
272 def test_replace_mode(self):
272 isp = self.isp
273 isp = self.isp
273 isp.input_mode = 'cell'
274 isp.input_mode = 'cell'
274 isp.push('x=1')
275 isp.push('x=1')
275 self.assertEqual(isp.source, 'x=1\n')
276 self.assertEqual(isp.source, 'x=1\n')
276 isp.push('x=2')
277 isp.push('x=2')
277 self.assertEqual(isp.source, 'x=2\n')
278 self.assertEqual(isp.source, 'x=2\n')
278
279
279 def test_push_accepts_more(self):
280 def test_push_accepts_more(self):
280 isp = self.isp
281 isp = self.isp
281 isp.push('x=1')
282 isp.push('x=1')
282 self.assertFalse(isp.push_accepts_more())
283 self.assertFalse(isp.push_accepts_more())
283
284
284 def test_push_accepts_more2(self):
285 def test_push_accepts_more2(self):
285 # In cell mode, inputs must be fed in whole blocks, so skip this test
286 # In cell mode, inputs must be fed in whole blocks, so skip this test
286 if self.isp.input_mode == 'cell': return
287 if self.isp.input_mode == 'cell': return
287
288
288 isp = self.isp
289 isp = self.isp
289 isp.push('if 1:')
290 isp.push('if 1:')
290 self.assertTrue(isp.push_accepts_more())
291 self.assertTrue(isp.push_accepts_more())
291 isp.push(' x=1')
292 isp.push(' x=1')
292 self.assertTrue(isp.push_accepts_more())
293 self.assertTrue(isp.push_accepts_more())
293 isp.push('')
294 isp.push('')
294 self.assertFalse(isp.push_accepts_more())
295 self.assertFalse(isp.push_accepts_more())
295
296
296 def test_push_accepts_more3(self):
297 def test_push_accepts_more3(self):
297 isp = self.isp
298 isp = self.isp
298 isp.push("x = (2+\n3)")
299 isp.push("x = (2+\n3)")
299 self.assertFalse(isp.push_accepts_more())
300 self.assertFalse(isp.push_accepts_more())
300
301
301 def test_push_accepts_more4(self):
302 def test_push_accepts_more4(self):
302 # In cell mode, inputs must be fed in whole blocks, so skip this test
303 # In cell mode, inputs must be fed in whole blocks, so skip this test
303 if self.isp.input_mode == 'cell': return
304 if self.isp.input_mode == 'cell': return
304
305
305 isp = self.isp
306 isp = self.isp
306 # When a multiline statement contains parens or multiline strings, we
307 # When a multiline statement contains parens or multiline strings, we
307 # shouldn't get confused.
308 # shouldn't get confused.
308 # FIXME: we should be able to better handle de-dents in statements like
309 # FIXME: we should be able to better handle de-dents in statements like
309 # multiline strings and multiline expressions (continued with \ or
310 # multiline strings and multiline expressions (continued with \ or
310 # parens). Right now we aren't handling the indentation tracking quite
311 # parens). Right now we aren't handling the indentation tracking quite
311 # correctly with this, though in practice it may not be too much of a
312 # correctly with this, though in practice it may not be too much of a
312 # problem. We'll need to see.
313 # problem. We'll need to see.
313 isp.push("if 1:")
314 isp.push("if 1:")
314 isp.push(" x = (2+")
315 isp.push(" x = (2+")
315 isp.push(" 3)")
316 isp.push(" 3)")
316 self.assertTrue(isp.push_accepts_more())
317 self.assertTrue(isp.push_accepts_more())
317 isp.push(" y = 3")
318 isp.push(" y = 3")
318 self.assertTrue(isp.push_accepts_more())
319 self.assertTrue(isp.push_accepts_more())
319 isp.push('')
320 isp.push('')
320 self.assertFalse(isp.push_accepts_more())
321 self.assertFalse(isp.push_accepts_more())
321
322
322 def test_push_accepts_more5(self):
323 def test_push_accepts_more5(self):
323 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 if self.isp.input_mode == 'cell': return
325 if self.isp.input_mode == 'cell': return
325
326
326 isp = self.isp
327 isp = self.isp
327 isp.push('try:')
328 isp.push('try:')
328 isp.push(' a = 5')
329 isp.push(' a = 5')
329 isp.push('except:')
330 isp.push('except:')
330 isp.push(' raise')
331 isp.push(' raise')
331 self.assertTrue(isp.push_accepts_more())
332 self.assertTrue(isp.push_accepts_more())
332
333
333 def test_continuation(self):
334 def test_continuation(self):
334 isp = self.isp
335 isp = self.isp
335 isp.push("import os, \\")
336 isp.push("import os, \\")
336 self.assertTrue(isp.push_accepts_more())
337 self.assertTrue(isp.push_accepts_more())
337 isp.push("sys")
338 isp.push("sys")
338 self.assertFalse(isp.push_accepts_more())
339 self.assertFalse(isp.push_accepts_more())
339
340
340 def test_syntax_error(self):
341 def test_syntax_error(self):
341 isp = self.isp
342 isp = self.isp
342 # Syntax errors immediately produce a 'ready' block, so the invalid
343 # Syntax errors immediately produce a 'ready' block, so the invalid
343 # Python can be sent to the kernel for evaluation with possible ipython
344 # Python can be sent to the kernel for evaluation with possible ipython
344 # special-syntax conversion.
345 # special-syntax conversion.
345 isp.push('run foo')
346 isp.push('run foo')
346 self.assertFalse(isp.push_accepts_more())
347 self.assertFalse(isp.push_accepts_more())
347
348
348 def test_unicode(self):
349 def test_unicode(self):
349 self.isp.push(u"PΓ©rez")
350 self.isp.push(u"PΓ©rez")
350 self.isp.push(u'\xc3\xa9')
351 self.isp.push(u'\xc3\xa9')
351 self.isp.push(u"u'\xc3\xa9'")
352 self.isp.push(u"u'\xc3\xa9'")
352
353
353 class InteractiveLoopTestCase(unittest.TestCase):
354 class InteractiveLoopTestCase(unittest.TestCase):
354 """Tests for an interactive loop like a python shell.
355 """Tests for an interactive loop like a python shell.
355 """
356 """
356 def check_ns(self, lines, ns):
357 def check_ns(self, lines, ns):
357 """Validate that the given input lines produce the resulting namespace.
358 """Validate that the given input lines produce the resulting namespace.
358
359
359 Note: the input lines are given exactly as they would be typed in an
360 Note: the input lines are given exactly as they would be typed in an
360 auto-indenting environment, as mini_interactive_loop above already does
361 auto-indenting environment, as mini_interactive_loop above already does
361 auto-indenting and prepends spaces to the input.
362 auto-indenting and prepends spaces to the input.
362 """
363 """
363 src = mini_interactive_loop(pseudo_input(lines))
364 src = mini_interactive_loop(pseudo_input(lines))
364 test_ns = {}
365 test_ns = {}
365 exec src in test_ns
366 exec src in test_ns
366 # We can't check that the provided ns is identical to the test_ns,
367 # We can't check that the provided ns is identical to the test_ns,
367 # because Python fills test_ns with extra keys (copyright, etc). But
368 # because Python fills test_ns with extra keys (copyright, etc). But
368 # we can check that the given dict is *contained* in test_ns
369 # we can check that the given dict is *contained* in test_ns
369 for k,v in ns.iteritems():
370 for k,v in ns.iteritems():
370 self.assertEqual(test_ns[k], v)
371 self.assertEqual(test_ns[k], v)
371
372
372 def test_simple(self):
373 def test_simple(self):
373 self.check_ns(['x=1'], dict(x=1))
374 self.check_ns(['x=1'], dict(x=1))
374
375
375 def test_simple2(self):
376 def test_simple2(self):
376 self.check_ns(['if 1:', 'x=2'], dict(x=2))
377 self.check_ns(['if 1:', 'x=2'], dict(x=2))
377
378
378 def test_xy(self):
379 def test_xy(self):
379 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
380 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
380
381
381 def test_abc(self):
382 def test_abc(self):
382 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
383 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
383
384
384 def test_multi(self):
385 def test_multi(self):
385 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
386 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
386
387
387
388
388 def test_LineInfo():
389 def test_LineInfo():
389 """Simple test for LineInfo construction and str()"""
390 """Simple test for LineInfo construction and str()"""
390 linfo = isp.LineInfo(' %cd /home')
391 linfo = isp.LineInfo(' %cd /home')
391 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
392 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
392
393
393 # Transformer tests
394 # Transformer tests
394 def transform_checker(tests, func):
395 def transform_checker(tests, func):
395 """Utility to loop over test inputs"""
396 """Utility to loop over test inputs"""
396 for inp, tr in tests:
397 for inp, tr in tests:
397 nt.assert_equals(func(inp), tr)
398 nt.assert_equals(func(inp), tr)
398
399
399 # Data for all the syntax tests in the form of lists of pairs of
400 # Data for all the syntax tests in the form of lists of pairs of
400 # raw/transformed input. We store it here as a global dict so that we can use
401 # raw/transformed input. We store it here as a global dict so that we can use
401 # it both within single-function tests and also to validate the behavior of the
402 # it both within single-function tests and also to validate the behavior of the
402 # larger objects
403 # larger objects
403
404
404 syntax = \
405 syntax = \
405 dict(assign_system =
406 dict(assign_system =
406 [('a =! ls', 'a = get_ipython().getoutput(u"ls")'),
407 [(i,py3compat.u_format(o)) for i,o in \
407 ('b = !ls', 'b = get_ipython().getoutput(u"ls")'),
408 [('a =! ls', 'a = get_ipython().getoutput({u}"ls")'),
409 ('b = !ls', 'b = get_ipython().getoutput({u}"ls")'),
408 ('x=1', 'x=1'), # normal input is unmodified
410 ('x=1', 'x=1'), # normal input is unmodified
409 (' ',' '), # blank lines are kept intact
411 (' ',' '), # blank lines are kept intact
410 ],
412 ]],
411
413
412 assign_magic =
414 assign_magic =
413 [('a =% who', 'a = get_ipython().magic(u"who")'),
415 [(i,py3compat.u_format(o)) for i,o in \
414 ('b = %who', 'b = get_ipython().magic(u"who")'),
416 [('a =% who', 'a = get_ipython().magic({u}"who")'),
417 ('b = %who', 'b = get_ipython().magic({u}"who")'),
415 ('x=1', 'x=1'), # normal input is unmodified
418 ('x=1', 'x=1'), # normal input is unmodified
416 (' ',' '), # blank lines are kept intact
419 (' ',' '), # blank lines are kept intact
417 ],
420 ]],
418
421
419 classic_prompt =
422 classic_prompt =
420 [('>>> x=1', 'x=1'),
423 [('>>> x=1', 'x=1'),
421 ('x=1', 'x=1'), # normal input is unmodified
424 ('x=1', 'x=1'), # normal input is unmodified
422 (' ', ' '), # blank lines are kept intact
425 (' ', ' '), # blank lines are kept intact
423 ('... ', ''), # continuation prompts
426 ('... ', ''), # continuation prompts
424 ],
427 ],
425
428
426 ipy_prompt =
429 ipy_prompt =
427 [('In [1]: x=1', 'x=1'),
430 [('In [1]: x=1', 'x=1'),
428 ('x=1', 'x=1'), # normal input is unmodified
431 ('x=1', 'x=1'), # normal input is unmodified
429 (' ',' '), # blank lines are kept intact
432 (' ',' '), # blank lines are kept intact
430 (' ....: ', ''), # continuation prompts
433 (' ....: ', ''), # continuation prompts
431 ],
434 ],
432
435
433 # Tests for the escape transformer to leave normal code alone
436 # Tests for the escape transformer to leave normal code alone
434 escaped_noesc =
437 escaped_noesc =
435 [ (' ', ' '),
438 [ (' ', ' '),
436 ('x=1', 'x=1'),
439 ('x=1', 'x=1'),
437 ],
440 ],
438
441
439 # System calls
442 # System calls
440 escaped_shell =
443 escaped_shell =
441 [ ('!ls', 'get_ipython().system(u"ls")'),
444 [(i,py3compat.u_format(o)) for i,o in \
445 [ ('!ls', 'get_ipython().system({u}"ls")'),
442 # Double-escape shell, this means to capture the output of the
446 # Double-escape shell, this means to capture the output of the
443 # subprocess and return it
447 # subprocess and return it
444 ('!!ls', 'get_ipython().getoutput(u"ls")'),
448 ('!!ls', 'get_ipython().getoutput({u}"ls")'),
445 ],
449 ]],
446
450
447 # Help/object info
451 # Help/object info
448 escaped_help =
452 escaped_help =
453 [(i,py3compat.u_format(o)) for i,o in \
449 [ ('?', 'get_ipython().show_usage()'),
454 [ ('?', 'get_ipython().show_usage()'),
450 ('?x1', 'get_ipython().magic(u"pinfo x1")'),
455 ('?x1', 'get_ipython().magic({u}"pinfo x1")'),
451 ('??x2', 'get_ipython().magic(u"pinfo2 x2")'),
456 ('??x2', 'get_ipython().magic({u}"pinfo2 x2")'),
452 ('?a.*s', 'get_ipython().magic(u"psearch a.*s")'),
457 ('?a.*s', 'get_ipython().magic({u}"psearch a.*s")'),
453 ('?%hist', 'get_ipython().magic(u"pinfo %hist")'),
458 ('?%hist', 'get_ipython().magic({u}"pinfo %hist")'),
454 ('?abc = qwe', 'get_ipython().magic(u"pinfo abc")'),
459 ('?abc = qwe', 'get_ipython().magic({u}"pinfo abc")'),
455 ],
460 ]],
456
461
457 end_help =
462 end_help =
458 [ ('x3?', 'get_ipython().magic(u"pinfo x3")'),
463 [(i,py3compat.u_format(o)) for i,o in \
459 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
464 [ ('x3?', 'get_ipython().magic({u}"pinfo x3")'),
460 ('%hist?', 'get_ipython().magic(u"pinfo %hist")'),
465 ('x4??', 'get_ipython().magic({u}"pinfo2 x4")'),
461 ('f*?', 'get_ipython().magic(u"psearch f*")'),
466 ('%hist?', 'get_ipython().magic({u}"pinfo %hist")'),
462 ('ax.*aspe*?', 'get_ipython().magic(u"psearch ax.*aspe*")'),
467 ('f*?', 'get_ipython().magic({u}"psearch f*")'),
463 ('a = abc?', 'get_ipython().magic(u"pinfo abc", next_input=u"a = abc")'),
468 ('ax.*aspe*?', 'get_ipython().magic({u}"psearch ax.*aspe*")'),
464 ('a = abc.qe??', 'get_ipython().magic(u"pinfo2 abc.qe", next_input=u"a = abc.qe")'),
469 ('a = abc?', 'get_ipython().magic({u}"pinfo abc", next_input={u}"a = abc")'),
465 ('a = *.items?', 'get_ipython().magic(u"psearch *.items", next_input=u"a = *.items")'),
470 ('a = abc.qe??', 'get_ipython().magic({u}"pinfo2 abc.qe", next_input={u}"a = abc.qe")'),
466 ('plot(a?', 'get_ipython().magic(u"pinfo a", next_input=u"plot(a")'),
471 ('a = *.items?', 'get_ipython().magic({u}"psearch *.items", next_input={u}"a = *.items")'),
472 ('plot(a?', 'get_ipython().magic({u}"pinfo a", next_input={u}"plot(a")'),
467 ('a*2 #comment?', 'a*2 #comment?'),
473 ('a*2 #comment?', 'a*2 #comment?'),
468 ],
474 ]],
469
475
470 # Explicit magic calls
476 # Explicit magic calls
471 escaped_magic =
477 escaped_magic =
472 [ ('%cd', 'get_ipython().magic(u"cd")'),
478 [(i,py3compat.u_format(o)) for i,o in \
473 ('%cd /home', 'get_ipython().magic(u"cd /home")'),
479 [ ('%cd', 'get_ipython().magic({u}"cd")'),
474 (' %magic', ' get_ipython().magic(u"magic")'),
480 ('%cd /home', 'get_ipython().magic({u}"cd /home")'),
475 ],
481 (' %magic', ' get_ipython().magic({u}"magic")'),
482 ]],
476
483
477 # Quoting with separate arguments
484 # Quoting with separate arguments
478 escaped_quote =
485 escaped_quote =
479 [ (',f', 'f("")'),
486 [ (',f', 'f("")'),
480 (',f x', 'f("x")'),
487 (',f x', 'f("x")'),
481 (' ,f y', ' f("y")'),
488 (' ,f y', ' f("y")'),
482 (',f a b', 'f("a", "b")'),
489 (',f a b', 'f("a", "b")'),
483 ],
490 ],
484
491
485 # Quoting with single argument
492 # Quoting with single argument
486 escaped_quote2 =
493 escaped_quote2 =
487 [ (';f', 'f("")'),
494 [ (';f', 'f("")'),
488 (';f x', 'f("x")'),
495 (';f x', 'f("x")'),
489 (' ;f y', ' f("y")'),
496 (' ;f y', ' f("y")'),
490 (';f a b', 'f("a b")'),
497 (';f a b', 'f("a b")'),
491 ],
498 ],
492
499
493 # Simply apply parens
500 # Simply apply parens
494 escaped_paren =
501 escaped_paren =
495 [ ('/f', 'f()'),
502 [ ('/f', 'f()'),
496 ('/f x', 'f(x)'),
503 ('/f x', 'f(x)'),
497 (' /f y', ' f(y)'),
504 (' /f y', ' f(y)'),
498 ('/f a b', 'f(a, b)'),
505 ('/f a b', 'f(a, b)'),
499 ],
506 ],
500
507
501 # Check that we transform prompts before other transforms
508 # Check that we transform prompts before other transforms
502 mixed =
509 mixed =
503 [ ('In [1]: %lsmagic', 'get_ipython().magic(u"lsmagic")'),
510 [(i,py3compat.u_format(o)) for i,o in \
504 ('>>> %lsmagic', 'get_ipython().magic(u"lsmagic")'),
511 [ ('In [1]: %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
505 ('In [2]: !ls', 'get_ipython().system(u"ls")'),
512 ('>>> %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
506 ('In [3]: abs?', 'get_ipython().magic(u"pinfo abs")'),
513 ('In [2]: !ls', 'get_ipython().system({u}"ls")'),
507 ('In [4]: b = %who', 'b = get_ipython().magic(u"who")'),
514 ('In [3]: abs?', 'get_ipython().magic({u}"pinfo abs")'),
508 ],
515 ('In [4]: b = %who', 'b = get_ipython().magic({u}"who")'),
516 ]],
509 )
517 )
510
518
511 # multiline syntax examples. Each of these should be a list of lists, with
519 # multiline syntax examples. Each of these should be a list of lists, with
512 # each entry itself having pairs of raw/transformed input. The union (with
520 # each entry itself having pairs of raw/transformed input. The union (with
513 # '\n'.join() of the transformed inputs is what the splitter should produce
521 # '\n'.join() of the transformed inputs is what the splitter should produce
514 # when fed the raw lines one at a time via push.
522 # when fed the raw lines one at a time via push.
515 syntax_ml = \
523 syntax_ml = \
516 dict(classic_prompt =
524 dict(classic_prompt =
517 [ [('>>> for i in range(10):','for i in range(10):'),
525 [ [('>>> for i in range(10):','for i in range(10):'),
518 ('... print i',' print i'),
526 ('... print i',' print i'),
519 ('... ', ''),
527 ('... ', ''),
520 ],
528 ],
521 ],
529 ],
522
530
523 ipy_prompt =
531 ipy_prompt =
524 [ [('In [24]: for i in range(10):','for i in range(10):'),
532 [ [('In [24]: for i in range(10):','for i in range(10):'),
525 (' ....: print i',' print i'),
533 (' ....: print i',' print i'),
526 (' ....: ', ''),
534 (' ....: ', ''),
527 ],
535 ],
528 ],
536 ],
529 )
537 )
530
538
531
539
532 def test_assign_system():
540 def test_assign_system():
533 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
541 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
534
542
535
543
536 def test_assign_magic():
544 def test_assign_magic():
537 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
545 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
538
546
539
547
540 def test_classic_prompt():
548 def test_classic_prompt():
541 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
549 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
542 for example in syntax_ml['classic_prompt']:
550 for example in syntax_ml['classic_prompt']:
543 transform_checker(example, isp.transform_classic_prompt)
551 transform_checker(example, isp.transform_classic_prompt)
544
552
545
553
546 def test_ipy_prompt():
554 def test_ipy_prompt():
547 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
555 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
548 for example in syntax_ml['ipy_prompt']:
556 for example in syntax_ml['ipy_prompt']:
549 transform_checker(example, isp.transform_ipy_prompt)
557 transform_checker(example, isp.transform_ipy_prompt)
550
558
551 def test_end_help():
559 def test_end_help():
552 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
560 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
553
561
554 def test_escaped_noesc():
562 def test_escaped_noesc():
555 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
563 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
556
564
557
565
558 def test_escaped_shell():
566 def test_escaped_shell():
559 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
567 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
560
568
561
569
562 def test_escaped_help():
570 def test_escaped_help():
563 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
571 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
564
572
565
573
566 def test_escaped_magic():
574 def test_escaped_magic():
567 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
575 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
568
576
569
577
570 def test_escaped_quote():
578 def test_escaped_quote():
571 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
579 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
572
580
573
581
574 def test_escaped_quote2():
582 def test_escaped_quote2():
575 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
583 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
576
584
577
585
578 def test_escaped_paren():
586 def test_escaped_paren():
579 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
587 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
580
588
581
589
582 class IPythonInputTestCase(InputSplitterTestCase):
590 class IPythonInputTestCase(InputSplitterTestCase):
583 """By just creating a new class whose .isp is a different instance, we
591 """By just creating a new class whose .isp is a different instance, we
584 re-run the same test battery on the new input splitter.
592 re-run the same test battery on the new input splitter.
585
593
586 In addition, this runs the tests over the syntax and syntax_ml dicts that
594 In addition, this runs the tests over the syntax and syntax_ml dicts that
587 were tested by individual functions, as part of the OO interface.
595 were tested by individual functions, as part of the OO interface.
588
596
589 It also makes some checks on the raw buffer storage.
597 It also makes some checks on the raw buffer storage.
590 """
598 """
591
599
592 def setUp(self):
600 def setUp(self):
593 self.isp = isp.IPythonInputSplitter(input_mode='line')
601 self.isp = isp.IPythonInputSplitter(input_mode='line')
594
602
595 def test_syntax(self):
603 def test_syntax(self):
596 """Call all single-line syntax tests from the main object"""
604 """Call all single-line syntax tests from the main object"""
597 isp = self.isp
605 isp = self.isp
598 for example in syntax.itervalues():
606 for example in syntax.itervalues():
599 for raw, out_t in example:
607 for raw, out_t in example:
600 if raw.startswith(' '):
608 if raw.startswith(' '):
601 continue
609 continue
602
610
603 isp.push(raw)
611 isp.push(raw)
604 out, out_raw = isp.source_raw_reset()
612 out, out_raw = isp.source_raw_reset()
605 self.assertEqual(out.rstrip(), out_t,
613 self.assertEqual(out.rstrip(), out_t,
606 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
614 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
607 self.assertEqual(out_raw.rstrip(), raw.rstrip())
615 self.assertEqual(out_raw.rstrip(), raw.rstrip())
608
616
609 def test_syntax_multiline(self):
617 def test_syntax_multiline(self):
610 isp = self.isp
618 isp = self.isp
611 for example in syntax_ml.itervalues():
619 for example in syntax_ml.itervalues():
612 out_t_parts = []
620 out_t_parts = []
613 raw_parts = []
621 raw_parts = []
614 for line_pairs in example:
622 for line_pairs in example:
615 for lraw, out_t_part in line_pairs:
623 for lraw, out_t_part in line_pairs:
616 isp.push(lraw)
624 isp.push(lraw)
617 out_t_parts.append(out_t_part)
625 out_t_parts.append(out_t_part)
618 raw_parts.append(lraw)
626 raw_parts.append(lraw)
619
627
620 out, out_raw = isp.source_raw_reset()
628 out, out_raw = isp.source_raw_reset()
621 out_t = '\n'.join(out_t_parts).rstrip()
629 out_t = '\n'.join(out_t_parts).rstrip()
622 raw = '\n'.join(raw_parts).rstrip()
630 raw = '\n'.join(raw_parts).rstrip()
623 self.assertEqual(out.rstrip(), out_t)
631 self.assertEqual(out.rstrip(), out_t)
624 self.assertEqual(out_raw.rstrip(), raw)
632 self.assertEqual(out_raw.rstrip(), raw)
625
633
626
634
627 class BlockIPythonInputTestCase(IPythonInputTestCase):
635 class BlockIPythonInputTestCase(IPythonInputTestCase):
628
636
629 # Deactivate tests that don't make sense for the block mode
637 # Deactivate tests that don't make sense for the block mode
630 test_push3 = test_split = lambda s: None
638 test_push3 = test_split = lambda s: None
631
639
632 def setUp(self):
640 def setUp(self):
633 self.isp = isp.IPythonInputSplitter(input_mode='cell')
641 self.isp = isp.IPythonInputSplitter(input_mode='cell')
634
642
635 def test_syntax_multiline(self):
643 def test_syntax_multiline(self):
636 isp = self.isp
644 isp = self.isp
637 for example in syntax_ml.itervalues():
645 for example in syntax_ml.itervalues():
638 raw_parts = []
646 raw_parts = []
639 out_t_parts = []
647 out_t_parts = []
640 for line_pairs in example:
648 for line_pairs in example:
641 for raw, out_t_part in line_pairs:
649 for raw, out_t_part in line_pairs:
642 raw_parts.append(raw)
650 raw_parts.append(raw)
643 out_t_parts.append(out_t_part)
651 out_t_parts.append(out_t_part)
644
652
645 raw = '\n'.join(raw_parts)
653 raw = '\n'.join(raw_parts)
646 out_t = '\n'.join(out_t_parts)
654 out_t = '\n'.join(out_t_parts)
647
655
648 isp.push(raw)
656 isp.push(raw)
649 out, out_raw = isp.source_raw_reset()
657 out, out_raw = isp.source_raw_reset()
650 # Match ignoring trailing whitespace
658 # Match ignoring trailing whitespace
651 self.assertEqual(out.rstrip(), out_t.rstrip())
659 self.assertEqual(out.rstrip(), out_t.rstrip())
652 self.assertEqual(out_raw.rstrip(), raw.rstrip())
660 self.assertEqual(out_raw.rstrip(), raw.rstrip())
653
661
654
662
655 #-----------------------------------------------------------------------------
663 #-----------------------------------------------------------------------------
656 # Main - use as a script, mostly for developer experiments
664 # Main - use as a script, mostly for developer experiments
657 #-----------------------------------------------------------------------------
665 #-----------------------------------------------------------------------------
658
666
659 if __name__ == '__main__':
667 if __name__ == '__main__':
660 # A simple demo for interactive experimentation. This code will not get
668 # A simple demo for interactive experimentation. This code will not get
661 # picked up by any test suite.
669 # picked up by any test suite.
662 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
670 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
663
671
664 # configure here the syntax to use, prompt and whether to autoindent
672 # configure here the syntax to use, prompt and whether to autoindent
665 #isp, start_prompt = InputSplitter(), '>>> '
673 #isp, start_prompt = InputSplitter(), '>>> '
666 isp, start_prompt = IPythonInputSplitter(), 'In> '
674 isp, start_prompt = IPythonInputSplitter(), 'In> '
667
675
668 autoindent = True
676 autoindent = True
669 #autoindent = False
677 #autoindent = False
670
678
671 try:
679 try:
672 while True:
680 while True:
673 prompt = start_prompt
681 prompt = start_prompt
674 while isp.push_accepts_more():
682 while isp.push_accepts_more():
675 indent = ' '*isp.indent_spaces
683 indent = ' '*isp.indent_spaces
676 if autoindent:
684 if autoindent:
677 line = indent + raw_input(prompt+indent)
685 line = indent + raw_input(prompt+indent)
678 else:
686 else:
679 line = raw_input(prompt)
687 line = raw_input(prompt)
680 isp.push(line)
688 isp.push(line)
681 prompt = '... '
689 prompt = '... '
682
690
683 # Here we just return input so we can use it in a test suite, but a
691 # Here we just return input so we can use it in a test suite, but a
684 # real interpreter would instead send it for execution somewhere.
692 # real interpreter would instead send it for execution somewhere.
685 #src = isp.source; raise EOFError # dbg
693 #src = isp.source; raise EOFError # dbg
686 src, raw = isp.source_raw_reset()
694 src, raw = isp.source_raw_reset()
687 print 'Input source was:\n', src
695 print 'Input source was:\n', src
688 print 'Raw source was:\n', raw
696 print 'Raw source was:\n', raw
689 except EOFError:
697 except EOFError:
690 print 'Bye'
698 print 'Bye'
@@ -1,271 +1,271 b''
1 """Tests for the key interactiveshell module, where the main ipython class is defined.
1 """Tests for the key interactiveshell module, where the main ipython class is defined.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # stdlib
7 # stdlib
8 import os
8 import os
9 import shutil
9 import shutil
10 import tempfile
10 import tempfile
11
11
12 # third party
12 # third party
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 # our own packages
15 # our own packages
16 from IPython.testing import decorators as dec
16 from IPython.testing import decorators as dec
17 from IPython.testing.globalipapp import get_ipython
17 from IPython.testing.globalipapp import get_ipython
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Globals
20 # Globals
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 # Get the public instance of IPython
23 # Get the public instance of IPython
24 ip = get_ipython()
24 ip = get_ipython()
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Test functions
27 # Test functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 @dec.parametric
30 @dec.parametric
31 def test_reset():
31 def test_reset():
32 """reset must clear most namespaces."""
32 """reset must clear most namespaces."""
33 # The number of variables in the private user_ns_hidden is not zero, but it
33 # The number of variables in the private user_ns_hidden is not zero, but it
34 # should be constant regardless of what we do
34 # should be constant regardless of what we do
35 nvars_config_ns = len(ip.user_ns_hidden)
35 nvars_config_ns = len(ip.user_ns_hidden)
36
36
37 # Check that reset runs without error
37 # Check that reset runs without error
38 ip.reset()
38 ip.reset()
39
39
40 # Once we've reset it (to clear of any junk that might have been there from
40 # Once we've reset it (to clear of any junk that might have been there from
41 # other tests, we can count how many variables are in the user's namespace
41 # other tests, we can count how many variables are in the user's namespace
42 nvars_user_ns = len(ip.user_ns)
42 nvars_user_ns = len(ip.user_ns)
43
43
44 # Now add a few variables to user_ns, and check that reset clears them
44 # Now add a few variables to user_ns, and check that reset clears them
45 ip.user_ns['x'] = 1
45 ip.user_ns['x'] = 1
46 ip.user_ns['y'] = 1
46 ip.user_ns['y'] = 1
47 ip.reset()
47 ip.reset()
48
48
49 # Finally, check that all namespaces have only as many variables as we
49 # Finally, check that all namespaces have only as many variables as we
50 # expect to find in them:
50 # expect to find in them:
51 for ns in ip.ns_refs_table:
51 for ns in ip.ns_refs_table:
52 if ns is ip.user_ns:
52 if ns is ip.user_ns:
53 nvars_expected = nvars_user_ns
53 nvars_expected = nvars_user_ns
54 elif ns is ip.user_ns_hidden:
54 elif ns is ip.user_ns_hidden:
55 nvars_expected = nvars_config_ns
55 nvars_expected = nvars_config_ns
56 else:
56 else:
57 nvars_expected = 0
57 nvars_expected = 0
58
58
59 yield nt.assert_equals(len(ns), nvars_expected)
59 yield nt.assert_equals(len(ns), nvars_expected)
60
60
61
61
62 # Tests for reporting of exceptions in various modes, handling of SystemExit,
62 # Tests for reporting of exceptions in various modes, handling of SystemExit,
63 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
63 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
64
64
65 def doctest_tb_plain():
65 def doctest_tb_plain():
66 """
66 """
67 In [18]: xmode plain
67 In [18]: xmode plain
68 Exception reporting mode: Plain
68 Exception reporting mode: Plain
69
69
70 In [19]: run simpleerr.py
70 In [19]: run simpleerr.py
71 Traceback (most recent call last):
71 Traceback (most recent call last):
72 ...line 32, in <module>
72 ...line 32, in <module>
73 bar(mode)
73 bar(mode)
74 ...line 16, in bar
74 ...line 16, in bar
75 div0()
75 div0()
76 ...line 8, in div0
76 ...line 8, in div0
77 x/y
77 x/y
78 ZeroDivisionError: ...
78 ZeroDivisionError: ...
79 """
79 """
80
80
81
81
82 def doctest_tb_context():
82 def doctest_tb_context():
83 """
83 """
84 In [3]: xmode context
84 In [3]: xmode context
85 Exception reporting mode: Context
85 Exception reporting mode: Context
86
86
87 In [4]: run simpleerr.py
87 In [4]: run simpleerr.py
88 ---------------------------------------------------------------------------
88 ---------------------------------------------------------------------------
89 ZeroDivisionError Traceback (most recent call last)
89 ZeroDivisionError Traceback (most recent call last)
90 <BLANKLINE>
90 <BLANKLINE>
91 ... in <module>()
91 ... in <module>()
92 30 mode = 'div'
92 30 mode = 'div'
93 31
93 31
94 ---> 32 bar(mode)
94 ---> 32 bar(mode)
95 <BLANKLINE>
95 <BLANKLINE>
96 ... in bar(mode)
96 ... in bar(mode)
97 14 "bar"
97 14 "bar"
98 15 if mode=='div':
98 15 if mode=='div':
99 ---> 16 div0()
99 ---> 16 div0()
100 17 elif mode=='exit':
100 17 elif mode=='exit':
101 18 try:
101 18 try:
102 <BLANKLINE>
102 <BLANKLINE>
103 ... in div0()
103 ... in div0()
104 6 x = 1
104 6 x = 1
105 7 y = 0
105 7 y = 0
106 ----> 8 x/y
106 ----> 8 x/y
107 9
107 9
108 10 def sysexit(stat, mode):
108 10 def sysexit(stat, mode):
109 <BLANKLINE>
109 <BLANKLINE>
110 ZeroDivisionError: ...
110 ZeroDivisionError: ...
111 """
111 """
112
112
113
113
114 def doctest_tb_verbose():
114 def doctest_tb_verbose():
115 """
115 """
116 In [5]: xmode verbose
116 In [5]: xmode verbose
117 Exception reporting mode: Verbose
117 Exception reporting mode: Verbose
118
118
119 In [6]: run simpleerr.py
119 In [6]: run simpleerr.py
120 ---------------------------------------------------------------------------
120 ---------------------------------------------------------------------------
121 ZeroDivisionError Traceback (most recent call last)
121 ZeroDivisionError Traceback (most recent call last)
122 <BLANKLINE>
122 <BLANKLINE>
123 ... in <module>()
123 ... in <module>()
124 30 mode = 'div'
124 30 mode = 'div'
125 31
125 31
126 ---> 32 bar(mode)
126 ---> 32 bar(mode)
127 global bar = <function bar at ...>
127 global bar = <function bar at ...>
128 global mode = 'div'
128 global mode = 'div'
129 <BLANKLINE>
129 <BLANKLINE>
130 ... in bar(mode='div')
130 ... in bar(mode='div')
131 14 "bar"
131 14 "bar"
132 15 if mode=='div':
132 15 if mode=='div':
133 ---> 16 div0()
133 ---> 16 div0()
134 global div0 = <function div0 at ...>
134 global div0 = <function div0 at ...>
135 17 elif mode=='exit':
135 17 elif mode=='exit':
136 18 try:
136 18 try:
137 <BLANKLINE>
137 <BLANKLINE>
138 ... in div0()
138 ... in div0()
139 6 x = 1
139 6 x = 1
140 7 y = 0
140 7 y = 0
141 ----> 8 x/y
141 ----> 8 x/y
142 x = 1
142 x = 1
143 y = 0
143 y = 0
144 9
144 9
145 10 def sysexit(stat, mode):
145 10 def sysexit(stat, mode):
146 <BLANKLINE>
146 <BLANKLINE>
147 ZeroDivisionError: ...
147 ZeroDivisionError: ...
148 """
148 """
149
149
150
150 @py3compat.u_format
151 def doctest_tb_sysexit():
151 def doctest_tb_sysexit():
152 """
152 """
153 In [17]: %xmode plain
153 In [17]: %xmode plain
154 Exception reporting mode: Plain
154 Exception reporting mode: Plain
155
155
156 In [18]: %run simpleerr.py exit
156 In [18]: %run simpleerr.py exit
157 An exception has occurred, use %tb to see the full traceback.
157 An exception has occurred, use %tb to see the full traceback.
158 SystemExit: (1, u'Mode = exit')
158 SystemExit: (1, {u}'Mode = exit')
159
159
160 In [19]: %run simpleerr.py exit 2
160 In [19]: %run simpleerr.py exit 2
161 An exception has occurred, use %tb to see the full traceback.
161 An exception has occurred, use %tb to see the full traceback.
162 SystemExit: (2, u'Mode = exit')
162 SystemExit: (2, {u}'Mode = exit')
163
163
164 In [20]: %tb
164 In [20]: %tb
165 Traceback (most recent call last):
165 Traceback (most recent call last):
166 File ... in <module>
166 File ... in <module>
167 bar(mode)
167 bar(mode)
168 File ... line 22, in bar
168 File ... line 22, in bar
169 sysexit(stat, mode)
169 sysexit(stat, mode)
170 File ... line 11, in sysexit
170 File ... line 11, in sysexit
171 raise SystemExit(stat, 'Mode = %s' % mode)
171 raise SystemExit(stat, 'Mode = %s' % mode)
172 SystemExit: (2, u'Mode = exit')
172 SystemExit: (2, {u}'Mode = exit')
173
173
174 In [21]: %xmode context
174 In [21]: %xmode context
175 Exception reporting mode: Context
175 Exception reporting mode: Context
176
176
177 In [22]: %tb
177 In [22]: %tb
178 ---------------------------------------------------------------------------
178 ---------------------------------------------------------------------------
179 SystemExit Traceback (most recent call last)
179 SystemExit Traceback (most recent call last)
180 <BLANKLINE>
180 <BLANKLINE>
181 ...<module>()
181 ...<module>()
182 30 mode = 'div'
182 30 mode = 'div'
183 31
183 31
184 ---> 32 bar(mode)
184 ---> 32 bar(mode)
185 <BLANKLINE>
185 <BLANKLINE>
186 ...bar(mode)
186 ...bar(mode)
187 20 except:
187 20 except:
188 21 stat = 1
188 21 stat = 1
189 ---> 22 sysexit(stat, mode)
189 ---> 22 sysexit(stat, mode)
190 23 else:
190 23 else:
191 24 raise ValueError('Unknown mode')
191 24 raise ValueError('Unknown mode')
192 <BLANKLINE>
192 <BLANKLINE>
193 ...sysexit(stat, mode)
193 ...sysexit(stat, mode)
194 9
194 9
195 10 def sysexit(stat, mode):
195 10 def sysexit(stat, mode):
196 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
196 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
197 12
197 12
198 13 def bar(mode):
198 13 def bar(mode):
199 <BLANKLINE>
199 <BLANKLINE>
200 SystemExit: (2, u'Mode = exit')
200 SystemExit: (2, {u}'Mode = exit')
201
201
202 In [23]: %xmode verbose
202 In [23]: %xmode verbose
203 Exception reporting mode: Verbose
203 Exception reporting mode: Verbose
204
204
205 In [24]: %tb
205 In [24]: %tb
206 ---------------------------------------------------------------------------
206 ---------------------------------------------------------------------------
207 SystemExit Traceback (most recent call last)
207 SystemExit Traceback (most recent call last)
208 <BLANKLINE>
208 <BLANKLINE>
209 ... in <module>()
209 ... in <module>()
210 30 mode = 'div'
210 30 mode = 'div'
211 31
211 31
212 ---> 32 bar(mode)
212 ---> 32 bar(mode)
213 global bar = <function bar at ...>
213 global bar = <function bar at ...>
214 global mode = u'exit'
214 global mode = {u}'exit'
215 <BLANKLINE>
215 <BLANKLINE>
216 ... in bar(mode=u'exit')
216 ... in bar(mode={u}'exit')
217 20 except:
217 20 except:
218 21 stat = 1
218 21 stat = 1
219 ---> 22 sysexit(stat, mode)
219 ---> 22 sysexit(stat, mode)
220 global sysexit = <function sysexit at ...>
220 global sysexit = <function sysexit at ...>
221 stat = 2
221 stat = 2
222 mode = u'exit'
222 mode = {u}'exit'
223 23 else:
223 23 else:
224 24 raise ValueError('Unknown mode')
224 24 raise ValueError('Unknown mode')
225 <BLANKLINE>
225 <BLANKLINE>
226 ... in sysexit(stat=2, mode=u'exit')
226 ... in sysexit(stat=2, mode={u}'exit')
227 9
227 9
228 10 def sysexit(stat, mode):
228 10 def sysexit(stat, mode):
229 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
229 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
230 global SystemExit = undefined
230 global SystemExit = undefined
231 stat = 2
231 stat = 2
232 mode = u'exit'
232 mode = {u}'exit'
233 12
233 12
234 13 def bar(mode):
234 13 def bar(mode):
235 <BLANKLINE>
235 <BLANKLINE>
236 SystemExit: (2, u'Mode = exit')
236 SystemExit: (2, {u}'Mode = exit')
237 """
237 """
238
238
239
239
240 def test_run_cell():
240 def test_run_cell():
241 import textwrap
241 import textwrap
242 ip.run_cell('a = 10\na+=1')
242 ip.run_cell('a = 10\na+=1')
243 ip.run_cell('assert a == 11\nassert 1')
243 ip.run_cell('assert a == 11\nassert 1')
244
244
245 nt.assert_equals(ip.user_ns['a'], 11)
245 nt.assert_equals(ip.user_ns['a'], 11)
246 complex = textwrap.dedent("""
246 complex = textwrap.dedent("""
247 if 1:
247 if 1:
248 print "hello"
248 print "hello"
249 if 1:
249 if 1:
250 print "world"
250 print "world"
251
251
252 if 2:
252 if 2:
253 print "foo"
253 print "foo"
254
254
255 if 3:
255 if 3:
256 print "bar"
256 print "bar"
257
257
258 if 4:
258 if 4:
259 print "bar"
259 print "bar"
260
260
261 """)
261 """)
262 # Simply verifies that this kind of input is run
262 # Simply verifies that this kind of input is run
263 ip.run_cell(complex)
263 ip.run_cell(complex)
264
264
265
265
266 def test_db():
266 def test_db():
267 """Test the internal database used for variable persistence."""
267 """Test the internal database used for variable persistence."""
268 ip.db['__unittest_'] = 12
268 ip.db['__unittest_'] = 12
269 nt.assert_equals(ip.db['__unittest_'], 12)
269 nt.assert_equals(ip.db['__unittest_'], 12)
270 del ip.db['__unittest_']
270 del ip.db['__unittest_']
271 assert '__unittest_' not in ip.db
271 assert '__unittest_' not in ip.db
@@ -1,462 +1,467 b''
1 """Tests for various magic functions.
1 """Tests for various magic functions.
2
2
3 Needs to be run by nose (to make ipython session available).
3 Needs to be run by nose (to make ipython session available).
4 """
4 """
5 from __future__ import absolute_import
5 from __future__ import absolute_import
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Imports
8 # Imports
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 import os
11 import os
12 import sys
12 import sys
13 import tempfile
13 import tempfile
14 import types
14 import types
15 from StringIO import StringIO
15 from StringIO import StringIO
16
16
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 from IPython.utils.path import get_long_path_name
19 from IPython.utils.path import get_long_path_name
20 from IPython.testing import decorators as dec
20 from IPython.testing import decorators as dec
21 from IPython.testing import tools as tt
21 from IPython.testing import tools as tt
22 from IPython.utils import py3compat
22
23
23 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
24 # Test functions begin
25 # Test functions begin
25 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
26 def test_rehashx():
27 def test_rehashx():
27 # clear up everything
28 # clear up everything
28 _ip = get_ipython()
29 _ip = get_ipython()
29 _ip.alias_manager.alias_table.clear()
30 _ip.alias_manager.alias_table.clear()
30 del _ip.db['syscmdlist']
31 del _ip.db['syscmdlist']
31
32
32 _ip.magic('rehashx')
33 _ip.magic('rehashx')
33 # Practically ALL ipython development systems will have more than 10 aliases
34 # Practically ALL ipython development systems will have more than 10 aliases
34
35
35 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
36 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
36 for key, val in _ip.alias_manager.alias_table.iteritems():
37 for key, val in _ip.alias_manager.alias_table.iteritems():
37 # we must strip dots from alias names
38 # we must strip dots from alias names
38 nt.assert_true('.' not in key)
39 nt.assert_true('.' not in key)
39
40
40 # rehashx must fill up syscmdlist
41 # rehashx must fill up syscmdlist
41 scoms = _ip.db['syscmdlist']
42 scoms = _ip.db['syscmdlist']
42 yield (nt.assert_true, len(scoms) > 10)
43 yield (nt.assert_true, len(scoms) > 10)
43
44
44
45
45 def test_magic_parse_options():
46 def test_magic_parse_options():
46 """Test that we don't mangle paths when parsing magic options."""
47 """Test that we don't mangle paths when parsing magic options."""
47 ip = get_ipython()
48 ip = get_ipython()
48 path = 'c:\\x'
49 path = 'c:\\x'
49 opts = ip.parse_options('-f %s' % path,'f:')[0]
50 opts = ip.parse_options('-f %s' % path,'f:')[0]
50 # argv splitting is os-dependent
51 # argv splitting is os-dependent
51 if os.name == 'posix':
52 if os.name == 'posix':
52 expected = 'c:x'
53 expected = 'c:x'
53 else:
54 else:
54 expected = path
55 expected = path
55 nt.assert_equals(opts['f'], expected)
56 nt.assert_equals(opts['f'], expected)
56
57
57
58
58 def doctest_hist_f():
59 def doctest_hist_f():
59 """Test %hist -f with temporary filename.
60 """Test %hist -f with temporary filename.
60
61
61 In [9]: import tempfile
62 In [9]: import tempfile
62
63
63 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
64 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
64
65
65 In [11]: %hist -nl -f $tfile 3
66 In [11]: %hist -nl -f $tfile 3
66
67
67 In [13]: import os; os.unlink(tfile)
68 In [13]: import os; os.unlink(tfile)
68 """
69 """
69
70
70
71
71 def doctest_hist_r():
72 def doctest_hist_r():
72 """Test %hist -r
73 """Test %hist -r
73
74
74 XXX - This test is not recording the output correctly. For some reason, in
75 XXX - This test is not recording the output correctly. For some reason, in
75 testing mode the raw history isn't getting populated. No idea why.
76 testing mode the raw history isn't getting populated. No idea why.
76 Disabling the output checking for now, though at least we do run it.
77 Disabling the output checking for now, though at least we do run it.
77
78
78 In [1]: 'hist' in _ip.lsmagic()
79 In [1]: 'hist' in _ip.lsmagic()
79 Out[1]: True
80 Out[1]: True
80
81
81 In [2]: x=1
82 In [2]: x=1
82
83
83 In [3]: %hist -rl 2
84 In [3]: %hist -rl 2
84 x=1 # random
85 x=1 # random
85 %hist -r 2
86 %hist -r 2
86 """
87 """
87
88
88 def doctest_hist_op():
89 def doctest_hist_op():
89 """Test %hist -op
90 """Test %hist -op
90
91
91 In [1]: class b:
92 In [1]: class b(float):
92 ...: pass
93 ...: pass
93 ...:
94 ...:
94
95
95 In [2]: class s(b):
96 In [2]: class s(object):
96 ...: def __str__(self):
97 ...: def __str__(self):
97 ...: return 's'
98 ...: return 's'
98 ...:
99 ...:
99
100
100 In [3]:
101 In [3]:
101
102
102 In [4]: class r(b):
103 In [4]: class r(b):
103 ...: def __repr__(self):
104 ...: def __repr__(self):
104 ...: return 'r'
105 ...: return 'r'
105 ...:
106 ...:
106
107
107 In [5]: class sr(s,r): pass
108 In [5]: class sr(s,r): pass
108 ...:
109 ...:
109
110
110 In [6]:
111 In [6]:
111
112
112 In [7]: bb=b()
113 In [7]: bb=b()
113
114
114 In [8]: ss=s()
115 In [8]: ss=s()
115
116
116 In [9]: rr=r()
117 In [9]: rr=r()
117
118
118 In [10]: ssrr=sr()
119 In [10]: ssrr=sr()
119
120
120 In [11]: bb
121 In [11]: 4.5
121 Out[11]: <...b instance at ...>
122 Out[11]: 4.5
122
123
123 In [12]: ss
124 In [12]: str(ss)
124 Out[12]: <...s instance at ...>
125 Out[12]: 's'
125
126
126 In [13]:
127 In [13]:
127
128
128 In [14]: %hist -op
129 In [14]: %hist -op
129 >>> class b:
130 >>> class b:
130 ... pass
131 ... pass
131 ...
132 ...
132 >>> class s(b):
133 >>> class s(b):
133 ... def __str__(self):
134 ... def __str__(self):
134 ... return 's'
135 ... return 's'
135 ...
136 ...
136 >>>
137 >>>
137 >>> class r(b):
138 >>> class r(b):
138 ... def __repr__(self):
139 ... def __repr__(self):
139 ... return 'r'
140 ... return 'r'
140 ...
141 ...
141 >>> class sr(s,r): pass
142 >>> class sr(s,r): pass
142 >>>
143 >>>
143 >>> bb=b()
144 >>> bb=b()
144 >>> ss=s()
145 >>> ss=s()
145 >>> rr=r()
146 >>> rr=r()
146 >>> ssrr=sr()
147 >>> ssrr=sr()
147 >>> bb
148 >>> 4.5
148 <...b instance at ...>
149 4.5
149 >>> ss
150 >>> str(ss)
150 <...s instance at ...>
151 's'
151 >>>
152 >>>
152 """
153 """
153
154
154 def test_macro():
155 def test_macro():
155 ip = get_ipython()
156 ip = get_ipython()
156 ip.history_manager.reset() # Clear any existing history.
157 ip.history_manager.reset() # Clear any existing history.
157 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
158 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
158 for i, cmd in enumerate(cmds, start=1):
159 for i, cmd in enumerate(cmds, start=1):
159 ip.history_manager.store_inputs(i, cmd)
160 ip.history_manager.store_inputs(i, cmd)
160 ip.magic("macro test 1-3")
161 ip.magic("macro test 1-3")
161 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
162 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
162
163
163 # List macros.
164 # List macros.
164 assert "test" in ip.magic("macro")
165 assert "test" in ip.magic("macro")
165
166
166 def test_macro_run():
167 def test_macro_run():
167 """Test that we can run a multi-line macro successfully."""
168 """Test that we can run a multi-line macro successfully."""
168 ip = get_ipython()
169 ip = get_ipython()
169 ip.history_manager.reset()
170 ip.history_manager.reset()
170 cmds = ["a=10", "a+=1", "print a", "%macro test 2-3"]
171 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
172 "%macro test 2-3"]
171 for cmd in cmds:
173 for cmd in cmds:
172 ip.run_cell(cmd)
174 ip.run_cell(cmd)
173 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint a\n")
175 nt.assert_equal(ip.user_ns["test"].value,
176 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
174 original_stdout = sys.stdout
177 original_stdout = sys.stdout
175 new_stdout = StringIO()
178 new_stdout = StringIO()
176 sys.stdout = new_stdout
179 sys.stdout = new_stdout
177 try:
180 try:
178 ip.run_cell("test")
181 ip.run_cell("test")
179 nt.assert_true("12" in new_stdout.getvalue())
182 nt.assert_true("12" in new_stdout.getvalue())
180 ip.run_cell("test")
183 ip.run_cell("test")
181 nt.assert_true("13" in new_stdout.getvalue())
184 nt.assert_true("13" in new_stdout.getvalue())
182 finally:
185 finally:
183 sys.stdout = original_stdout
186 sys.stdout = original_stdout
184 new_stdout.close()
187 new_stdout.close()
185
188
186
189
187 # XXX failing for now, until we get clearcmd out of quarantine. But we should
190 # XXX failing for now, until we get clearcmd out of quarantine. But we should
188 # fix this and revert the skip to happen only if numpy is not around.
191 # fix this and revert the skip to happen only if numpy is not around.
189 #@dec.skipif_not_numpy
192 #@dec.skipif_not_numpy
190 @dec.skip_known_failure
193 @dec.skip_known_failure
191 def test_numpy_clear_array_undec():
194 def test_numpy_clear_array_undec():
192 from IPython.extensions import clearcmd
195 from IPython.extensions import clearcmd
193
196
194 _ip.ex('import numpy as np')
197 _ip.ex('import numpy as np')
195 _ip.ex('a = np.empty(2)')
198 _ip.ex('a = np.empty(2)')
196 yield (nt.assert_true, 'a' in _ip.user_ns)
199 yield (nt.assert_true, 'a' in _ip.user_ns)
197 _ip.magic('clear array')
200 _ip.magic('clear array')
198 yield (nt.assert_false, 'a' in _ip.user_ns)
201 yield (nt.assert_false, 'a' in _ip.user_ns)
199
202
200
203
201 # Multiple tests for clipboard pasting
204 # Multiple tests for clipboard pasting
202 @dec.parametric
205 @dec.parametric
203 def test_paste():
206 def test_paste():
204 _ip = get_ipython()
207 _ip = get_ipython()
205 def paste(txt, flags='-q'):
208 def paste(txt, flags='-q'):
206 """Paste input text, by default in quiet mode"""
209 """Paste input text, by default in quiet mode"""
207 hooks.clipboard_get = lambda : txt
210 hooks.clipboard_get = lambda : txt
208 _ip.magic('paste '+flags)
211 _ip.magic('paste '+flags)
209
212
210 # Inject fake clipboard hook but save original so we can restore it later
213 # Inject fake clipboard hook but save original so we can restore it later
211 hooks = _ip.hooks
214 hooks = _ip.hooks
212 user_ns = _ip.user_ns
215 user_ns = _ip.user_ns
213 original_clip = hooks.clipboard_get
216 original_clip = hooks.clipboard_get
214
217
215 try:
218 try:
216 # This try/except with an emtpy except clause is here only because
219 # This try/except with an emtpy except clause is here only because
217 # try/yield/finally is invalid syntax in Python 2.4. This will be
220 # try/yield/finally is invalid syntax in Python 2.4. This will be
218 # removed when we drop 2.4-compatibility, and the emtpy except below
221 # removed when we drop 2.4-compatibility, and the emtpy except below
219 # will be changed to a finally.
222 # will be changed to a finally.
220
223
221 # Run tests with fake clipboard function
224 # Run tests with fake clipboard function
222 user_ns.pop('x', None)
225 user_ns.pop('x', None)
223 paste('x=1')
226 paste('x=1')
224 yield nt.assert_equal(user_ns['x'], 1)
227 yield nt.assert_equal(user_ns['x'], 1)
225
228
226 user_ns.pop('x', None)
229 user_ns.pop('x', None)
227 paste('>>> x=2')
230 paste('>>> x=2')
228 yield nt.assert_equal(user_ns['x'], 2)
231 yield nt.assert_equal(user_ns['x'], 2)
229
232
230 paste("""
233 paste("""
231 >>> x = [1,2,3]
234 >>> x = [1,2,3]
232 >>> y = []
235 >>> y = []
233 >>> for i in x:
236 >>> for i in x:
234 ... y.append(i**2)
237 ... y.append(i**2)
235 ...
238 ...
236 """)
239 """)
237 yield nt.assert_equal(user_ns['x'], [1,2,3])
240 yield nt.assert_equal(user_ns['x'], [1,2,3])
238 yield nt.assert_equal(user_ns['y'], [1,4,9])
241 yield nt.assert_equal(user_ns['y'], [1,4,9])
239
242
240 # Now, test that paste -r works
243 # Now, test that paste -r works
241 user_ns.pop('x', None)
244 user_ns.pop('x', None)
242 yield nt.assert_false('x' in user_ns)
245 yield nt.assert_false('x' in user_ns)
243 _ip.magic('paste -r')
246 _ip.magic('paste -r')
244 yield nt.assert_equal(user_ns['x'], [1,2,3])
247 yield nt.assert_equal(user_ns['x'], [1,2,3])
245
248
246 # Also test paste echoing, by temporarily faking the writer
249 # Also test paste echoing, by temporarily faking the writer
247 w = StringIO()
250 w = StringIO()
248 writer = _ip.write
251 writer = _ip.write
249 _ip.write = w.write
252 _ip.write = w.write
250 code = """
253 code = """
251 a = 100
254 a = 100
252 b = 200"""
255 b = 200"""
253 try:
256 try:
254 paste(code,'')
257 paste(code,'')
255 out = w.getvalue()
258 out = w.getvalue()
256 finally:
259 finally:
257 _ip.write = writer
260 _ip.write = writer
258 yield nt.assert_equal(user_ns['a'], 100)
261 yield nt.assert_equal(user_ns['a'], 100)
259 yield nt.assert_equal(user_ns['b'], 200)
262 yield nt.assert_equal(user_ns['b'], 200)
260 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
263 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
261
264
262 finally:
265 finally:
263 # This should be in a finally clause, instead of the bare except above.
266 # This should be in a finally clause, instead of the bare except above.
264 # Restore original hook
267 # Restore original hook
265 hooks.clipboard_get = original_clip
268 hooks.clipboard_get = original_clip
266
269
267
270
268 def test_time():
271 def test_time():
269 _ip.magic('time None')
272 _ip.magic('time None')
270
273
271
274
275 @py3compat.doctest_refactor_print
272 def doctest_time():
276 def doctest_time():
273 """
277 """
274 In [10]: %time None
278 In [10]: %time None
275 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
279 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
276 Wall time: 0.00 s
280 Wall time: 0.00 s
277
281
278 In [11]: def f(kmjy):
282 In [11]: def f(kmjy):
279 ....: %time print 2*kmjy
283 ....: %time print 2*kmjy
280
284
281 In [12]: f(3)
285 In [12]: f(3)
282 6
286 6
283 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
287 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
284 Wall time: 0.00 s
288 Wall time: 0.00 s
285 """
289 """
286
290
287
291
288 def test_doctest_mode():
292 def test_doctest_mode():
289 "Toggle doctest_mode twice, it should be a no-op and run without error"
293 "Toggle doctest_mode twice, it should be a no-op and run without error"
290 _ip.magic('doctest_mode')
294 _ip.magic('doctest_mode')
291 _ip.magic('doctest_mode')
295 _ip.magic('doctest_mode')
292
296
293
297
294 def test_parse_options():
298 def test_parse_options():
295 """Tests for basic options parsing in magics."""
299 """Tests for basic options parsing in magics."""
296 # These are only the most minimal of tests, more should be added later. At
300 # These are only the most minimal of tests, more should be added later. At
297 # the very least we check that basic text/unicode calls work OK.
301 # the very least we check that basic text/unicode calls work OK.
298 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
302 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
299 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
303 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
300
304
301
305
302 def test_dirops():
306 def test_dirops():
303 """Test various directory handling operations."""
307 """Test various directory handling operations."""
304 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
308 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
305 curpath = os.getcwdu
309 curpath = os.getcwdu
306 startdir = os.getcwdu()
310 startdir = os.getcwdu()
307 ipdir = _ip.ipython_dir
311 ipdir = _ip.ipython_dir
308 try:
312 try:
309 _ip.magic('cd "%s"' % ipdir)
313 _ip.magic('cd "%s"' % ipdir)
310 nt.assert_equal(curpath(), ipdir)
314 nt.assert_equal(curpath(), ipdir)
311 _ip.magic('cd -')
315 _ip.magic('cd -')
312 nt.assert_equal(curpath(), startdir)
316 nt.assert_equal(curpath(), startdir)
313 _ip.magic('pushd "%s"' % ipdir)
317 _ip.magic('pushd "%s"' % ipdir)
314 nt.assert_equal(curpath(), ipdir)
318 nt.assert_equal(curpath(), ipdir)
315 _ip.magic('popd')
319 _ip.magic('popd')
316 nt.assert_equal(curpath(), startdir)
320 nt.assert_equal(curpath(), startdir)
317 finally:
321 finally:
318 os.chdir(startdir)
322 os.chdir(startdir)
319
323
320
324
321 def check_cpaste(code, should_fail=False):
325 def check_cpaste(code, should_fail=False):
322 """Execute code via 'cpaste' and ensure it was executed, unless
326 """Execute code via 'cpaste' and ensure it was executed, unless
323 should_fail is set.
327 should_fail is set.
324 """
328 """
325 _ip.user_ns['code_ran'] = False
329 _ip.user_ns['code_ran'] = False
326
330
327 src = StringIO()
331 src = StringIO()
328 src.write('\n')
332 src.write('\n')
329 src.write(code)
333 src.write(code)
330 src.write('\n--\n')
334 src.write('\n--\n')
331 src.seek(0)
335 src.seek(0)
332
336
333 stdin_save = sys.stdin
337 stdin_save = sys.stdin
334 sys.stdin = src
338 sys.stdin = src
335
339
336 try:
340 try:
337 _ip.magic('cpaste')
341 _ip.magic('cpaste')
338 except:
342 except:
339 if not should_fail:
343 if not should_fail:
340 raise AssertionError("Failure not expected : '%s'" %
344 raise AssertionError("Failure not expected : '%s'" %
341 code)
345 code)
342 else:
346 else:
343 assert _ip.user_ns['code_ran']
347 assert _ip.user_ns['code_ran']
344 if should_fail:
348 if should_fail:
345 raise AssertionError("Failure expected : '%s'" % code)
349 raise AssertionError("Failure expected : '%s'" % code)
346 finally:
350 finally:
347 sys.stdin = stdin_save
351 sys.stdin = stdin_save
348
352
349
353
350 def test_cpaste():
354 def test_cpaste():
351 """Test cpaste magic"""
355 """Test cpaste magic"""
352
356
353 def run():
357 def run():
354 """Marker function: sets a flag when executed.
358 """Marker function: sets a flag when executed.
355 """
359 """
356 _ip.user_ns['code_ran'] = True
360 _ip.user_ns['code_ran'] = True
357 return 'run' # return string so '+ run()' doesn't result in success
361 return 'run' # return string so '+ run()' doesn't result in success
358
362
359 tests = {'pass': ["> > > run()",
363 tests = {'pass': ["> > > run()",
360 ">>> > run()",
364 ">>> > run()",
361 "+++ run()",
365 "+++ run()",
362 "++ run()",
366 "++ run()",
363 " >>> run()"],
367 " >>> run()"],
364
368
365 'fail': ["+ + run()",
369 'fail': ["+ + run()",
366 " ++ run()"]}
370 " ++ run()"]}
367
371
368 _ip.user_ns['run'] = run
372 _ip.user_ns['run'] = run
369
373
370 for code in tests['pass']:
374 for code in tests['pass']:
371 check_cpaste(code)
375 check_cpaste(code)
372
376
373 for code in tests['fail']:
377 for code in tests['fail']:
374 check_cpaste(code, should_fail=True)
378 check_cpaste(code, should_fail=True)
375
379
376 def test_xmode():
380 def test_xmode():
377 # Calling xmode three times should be a no-op
381 # Calling xmode three times should be a no-op
378 xmode = _ip.InteractiveTB.mode
382 xmode = _ip.InteractiveTB.mode
379 for i in range(3):
383 for i in range(3):
380 _ip.magic("xmode")
384 _ip.magic("xmode")
381 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
385 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
382
386
383 def test_reset_hard():
387 def test_reset_hard():
384 monitor = []
388 monitor = []
385 class A(object):
389 class A(object):
386 def __del__(self):
390 def __del__(self):
387 monitor.append(1)
391 monitor.append(1)
388 def __repr__(self):
392 def __repr__(self):
389 return "<A instance>"
393 return "<A instance>"
390
394
391 _ip.user_ns["a"] = A()
395 _ip.user_ns["a"] = A()
392 _ip.run_cell("a")
396 _ip.run_cell("a")
393
397
394 nt.assert_equal(monitor, [])
398 nt.assert_equal(monitor, [])
395 _ip.magic_reset("-f")
399 _ip.magic_reset("-f")
396 nt.assert_equal(monitor, [1])
400 nt.assert_equal(monitor, [1])
397
401
398 class TestXdel(tt.TempFileMixin):
402 class TestXdel(tt.TempFileMixin):
399 def test_xdel(self):
403 def test_xdel(self):
400 """Test that references from %run are cleared by xdel."""
404 """Test that references from %run are cleared by xdel."""
401 src = ("class A(object):\n"
405 src = ("class A(object):\n"
402 " monitor = []\n"
406 " monitor = []\n"
403 " def __del__(self):\n"
407 " def __del__(self):\n"
404 " self.monitor.append(1)\n"
408 " self.monitor.append(1)\n"
405 "a = A()\n")
409 "a = A()\n")
406 self.mktmp(src)
410 self.mktmp(src)
407 # %run creates some hidden references...
411 # %run creates some hidden references...
408 _ip.magic("run %s" % self.fname)
412 _ip.magic("run %s" % self.fname)
409 # ... as does the displayhook.
413 # ... as does the displayhook.
410 _ip.run_cell("a")
414 _ip.run_cell("a")
411
415
412 monitor = _ip.user_ns["A"].monitor
416 monitor = _ip.user_ns["A"].monitor
413 nt.assert_equal(monitor, [])
417 nt.assert_equal(monitor, [])
414
418
415 _ip.magic("xdel a")
419 _ip.magic("xdel a")
416
420
417 # Check that a's __del__ method has been called.
421 # Check that a's __del__ method has been called.
418 nt.assert_equal(monitor, [1])
422 nt.assert_equal(monitor, [1])
419
423
420 def doctest_who():
424 def doctest_who():
421 """doctest for %who
425 """doctest for %who
422
426
423 In [1]: %reset -f
427 In [1]: %reset -f
424
428
425 In [2]: alpha = 123
429 In [2]: alpha = 123
426
430
427 In [3]: beta = 'beta'
431 In [3]: beta = 'beta'
428
432
429 In [4]: %who int
433 In [4]: %who int
430 alpha
434 alpha
431
435
432 In [5]: %who str
436 In [5]: %who str
433 beta
437 beta
434
438
435 In [6]: %whos
439 In [6]: %whos
436 Variable Type Data/Info
440 Variable Type Data/Info
437 ----------------------------
441 ----------------------------
438 alpha int 123
442 alpha int 123
439 beta str beta
443 beta str beta
440
444
441 In [7]: %who_ls
445 In [7]: %who_ls
442 Out[7]: ['alpha', 'beta']
446 Out[7]: ['alpha', 'beta']
443 """
447 """
444
448
449 @py3compat.u_format
445 def doctest_precision():
450 def doctest_precision():
446 """doctest for %precision
451 """doctest for %precision
447
452
448 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
453 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
449
454
450 In [2]: %precision 5
455 In [2]: %precision 5
451 Out[2]: u'%.5f'
456 Out[2]: {u}'%.5f'
452
457
453 In [3]: f.float_format
458 In [3]: f.float_format
454 Out[3]: u'%.5f'
459 Out[3]: {u}'%.5f'
455
460
456 In [4]: %precision %e
461 In [4]: %precision %e
457 Out[4]: u'%e'
462 Out[4]: {u}'%e'
458
463
459 In [5]: f(3.1415927)
464 In [5]: f(3.1415927)
460 Out[5]: u'3.141593e+00'
465 Out[5]: {u}'3.141593e+00'
461 """
466 """
462
467
@@ -1,208 +1,210 b''
1 """Tests for code execution (%run and related), which is particularly tricky.
1 """Tests for code execution (%run and related), which is particularly tricky.
2
2
3 Because of how %run manages namespaces, and the fact that we are trying here to
3 Because of how %run manages namespaces, and the fact that we are trying here to
4 verify subtle object deletion and reference counting issues, the %run tests
4 verify subtle object deletion and reference counting issues, the %run tests
5 will be kept in this separate file. This makes it easier to aggregate in one
5 will be kept in this separate file. This makes it easier to aggregate in one
6 place the tricks needed to handle it; most other magics are much easier to test
6 place the tricks needed to handle it; most other magics are much easier to test
7 and we do so in a common test_magic file.
7 and we do so in a common test_magic file.
8 """
8 """
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18
18
19 import nose.tools as nt
19 import nose.tools as nt
20 from nose import SkipTest
20 from nose import SkipTest
21
21
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23 from IPython.testing import tools as tt
23 from IPython.testing import tools as tt
24 from IPython.utils.py3compat import doctest_refactor_print
24
25
25 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
26 # Test functions begin
27 # Test functions begin
27 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
28
29
29 def doctest_refbug():
30 def doctest_refbug():
30 """Very nasty problem with references held by multiple runs of a script.
31 """Very nasty problem with references held by multiple runs of a script.
31 See: https://github.com/ipython/ipython/issues/141
32 See: https://github.com/ipython/ipython/issues/141
32
33
33 In [1]: _ip.clear_main_mod_cache()
34 In [1]: _ip.clear_main_mod_cache()
34 # random
35 # random
35
36
36 In [2]: %run refbug
37 In [2]: %run refbug
37
38
38 In [3]: call_f()
39 In [3]: call_f()
39 lowercased: hello
40 lowercased: hello
40
41
41 In [4]: %run refbug
42 In [4]: %run refbug
42
43
43 In [5]: call_f()
44 In [5]: call_f()
44 lowercased: hello
45 lowercased: hello
45 lowercased: hello
46 lowercased: hello
46 """
47 """
47
48
48
49
49 def doctest_run_builtins():
50 def doctest_run_builtins():
50 r"""Check that %run doesn't damage __builtins__.
51 r"""Check that %run doesn't damage __builtins__.
51
52
52 In [1]: import tempfile
53 In [1]: import tempfile
53
54
54 In [2]: bid1 = id(__builtins__)
55 In [2]: bid1 = id(__builtins__)
55
56
56 In [3]: fname = tempfile.mkstemp('.py')[1]
57 In [3]: fname = tempfile.mkstemp('.py')[1]
57
58
58 In [3]: f = open(fname,'w')
59 In [3]: f = open(fname,'w')
59
60
60 In [4]: f.write('pass\n')
61 In [4]: dummy= f.write('pass\n')
61
62
62 In [5]: f.flush()
63 In [5]: f.flush()
63
64
64 In [6]: t1 = type(__builtins__)
65 In [6]: t1 = type(__builtins__)
65
66
66 In [7]: %run $fname
67 In [7]: %run $fname
67
68
68 In [7]: f.close()
69 In [7]: f.close()
69
70
70 In [8]: bid2 = id(__builtins__)
71 In [8]: bid2 = id(__builtins__)
71
72
72 In [9]: t2 = type(__builtins__)
73 In [9]: t2 = type(__builtins__)
73
74
74 In [10]: t1 == t2
75 In [10]: t1 == t2
75 Out[10]: True
76 Out[10]: True
76
77
77 In [10]: bid1 == bid2
78 In [10]: bid1 == bid2
78 Out[10]: True
79 Out[10]: True
79
80
80 In [12]: try:
81 In [12]: try:
81 ....: os.unlink(fname)
82 ....: os.unlink(fname)
82 ....: except:
83 ....: except:
83 ....: pass
84 ....: pass
84 ....:
85 ....:
85 """
86 """
86
87
88 @doctest_refactor_print
87 def doctest_reset_del():
89 def doctest_reset_del():
88 """Test that resetting doesn't cause errors in __del__ methods.
90 """Test that resetting doesn't cause errors in __del__ methods.
89
91
90 In [2]: class A(object):
92 In [2]: class A(object):
91 ...: def __del__(self):
93 ...: def __del__(self):
92 ...: print str("Hi")
94 ...: print str("Hi")
93 ...:
95 ...:
94
96
95 In [3]: a = A()
97 In [3]: a = A()
96
98
97 In [4]: get_ipython().reset()
99 In [4]: get_ipython().reset()
98 Hi
100 Hi
99
101
100 In [5]: 1+1
102 In [5]: 1+1
101 Out[5]: 2
103 Out[5]: 2
102 """
104 """
103
105
104 # For some tests, it will be handy to organize them in a class with a common
106 # For some tests, it will be handy to organize them in a class with a common
105 # setup that makes a temp file
107 # setup that makes a temp file
106
108
107 class TestMagicRunPass(tt.TempFileMixin):
109 class TestMagicRunPass(tt.TempFileMixin):
108
110
109 def setup(self):
111 def setup(self):
110 """Make a valid python temp file."""
112 """Make a valid python temp file."""
111 self.mktmp('pass\n')
113 self.mktmp('pass\n')
112
114
113 def run_tmpfile(self):
115 def run_tmpfile(self):
114 _ip = get_ipython()
116 _ip = get_ipython()
115 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
117 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
116 # See below and ticket https://bugs.launchpad.net/bugs/366353
118 # See below and ticket https://bugs.launchpad.net/bugs/366353
117 _ip.magic('run %s' % self.fname)
119 _ip.magic('run %s' % self.fname)
118
120
119 def test_builtins_id(self):
121 def test_builtins_id(self):
120 """Check that %run doesn't damage __builtins__ """
122 """Check that %run doesn't damage __builtins__ """
121 _ip = get_ipython()
123 _ip = get_ipython()
122 # Test that the id of __builtins__ is not modified by %run
124 # Test that the id of __builtins__ is not modified by %run
123 bid1 = id(_ip.user_ns['__builtins__'])
125 bid1 = id(_ip.user_ns['__builtins__'])
124 self.run_tmpfile()
126 self.run_tmpfile()
125 bid2 = id(_ip.user_ns['__builtins__'])
127 bid2 = id(_ip.user_ns['__builtins__'])
126 tt.assert_equals(bid1, bid2)
128 tt.assert_equals(bid1, bid2)
127
129
128 def test_builtins_type(self):
130 def test_builtins_type(self):
129 """Check that the type of __builtins__ doesn't change with %run.
131 """Check that the type of __builtins__ doesn't change with %run.
130
132
131 However, the above could pass if __builtins__ was already modified to
133 However, the above could pass if __builtins__ was already modified to
132 be a dict (it should be a module) by a previous use of %run. So we
134 be a dict (it should be a module) by a previous use of %run. So we
133 also check explicitly that it really is a module:
135 also check explicitly that it really is a module:
134 """
136 """
135 _ip = get_ipython()
137 _ip = get_ipython()
136 self.run_tmpfile()
138 self.run_tmpfile()
137 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
139 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
138
140
139 def test_prompts(self):
141 def test_prompts(self):
140 """Test that prompts correctly generate after %run"""
142 """Test that prompts correctly generate after %run"""
141 self.run_tmpfile()
143 self.run_tmpfile()
142 _ip = get_ipython()
144 _ip = get_ipython()
143 p2 = str(_ip.displayhook.prompt2).strip()
145 p2 = str(_ip.displayhook.prompt2).strip()
144 nt.assert_equals(p2[:3], '...')
146 nt.assert_equals(p2[:3], '...')
145
147
146
148
147 class TestMagicRunSimple(tt.TempFileMixin):
149 class TestMagicRunSimple(tt.TempFileMixin):
148
150
149 def test_simpledef(self):
151 def test_simpledef(self):
150 """Test that simple class definitions work."""
152 """Test that simple class definitions work."""
151 src = ("class foo: pass\n"
153 src = ("class foo: pass\n"
152 "def f(): return foo()")
154 "def f(): return foo()")
153 self.mktmp(src)
155 self.mktmp(src)
154 _ip.magic('run %s' % self.fname)
156 _ip.magic('run %s' % self.fname)
155 _ip.run_cell('t = isinstance(f(), foo)')
157 _ip.run_cell('t = isinstance(f(), foo)')
156 nt.assert_true(_ip.user_ns['t'])
158 nt.assert_true(_ip.user_ns['t'])
157
159
158 def test_obj_del(self):
160 def test_obj_del(self):
159 """Test that object's __del__ methods are called on exit."""
161 """Test that object's __del__ methods are called on exit."""
160 if sys.platform == 'win32':
162 if sys.platform == 'win32':
161 try:
163 try:
162 import win32api
164 import win32api
163 except ImportError:
165 except ImportError:
164 raise SkipTest("Test requires pywin32")
166 raise SkipTest("Test requires pywin32")
165 src = ("class A(object):\n"
167 src = ("class A(object):\n"
166 " def __del__(self):\n"
168 " def __del__(self):\n"
167 " print 'object A deleted'\n"
169 " print 'object A deleted'\n"
168 "a = A()\n")
170 "a = A()\n")
169 self.mktmp(src)
171 self.mktmp(src)
170 tt.ipexec_validate(self.fname, 'object A deleted')
172 tt.ipexec_validate(self.fname, 'object A deleted')
171
173
172 @dec.skip_known_failure
174 @dec.skip_known_failure
173 def test_aggressive_namespace_cleanup(self):
175 def test_aggressive_namespace_cleanup(self):
174 """Test that namespace cleanup is not too aggressive GH-238
176 """Test that namespace cleanup is not too aggressive GH-238
175
177
176 Returning from another run magic deletes the namespace"""
178 Returning from another run magic deletes the namespace"""
177 # see ticket https://github.com/ipython/ipython/issues/238
179 # see ticket https://github.com/ipython/ipython/issues/238
178 class secondtmp(tt.TempFileMixin): pass
180 class secondtmp(tt.TempFileMixin): pass
179 empty = secondtmp()
181 empty = secondtmp()
180 empty.mktmp('')
182 empty.mktmp('')
181 src = ("ip = get_ipython()\n"
183 src = ("ip = get_ipython()\n"
182 "for i in range(5):\n"
184 "for i in range(5):\n"
183 " try:\n"
185 " try:\n"
184 " ip.magic('run %s')\n"
186 " ip.magic('run %s')\n"
185 " except NameError, e:\n"
187 " except NameError, e:\n"
186 " print i;break\n" % empty.fname)
188 " print i;break\n" % empty.fname)
187 self.mktmp(src)
189 self.mktmp(src)
188 _ip.magic('run %s' % self.fname)
190 _ip.magic('run %s' % self.fname)
189 _ip.run_cell('ip == get_ipython()')
191 _ip.run_cell('ip == get_ipython()')
190 tt.assert_equals(_ip.user_ns['i'], 5)
192 tt.assert_equals(_ip.user_ns['i'], 5)
191
193
192 @dec.skip_win32
194 @dec.skip_win32
193 def test_tclass(self):
195 def test_tclass(self):
194 mydir = os.path.dirname(__file__)
196 mydir = os.path.dirname(__file__)
195 tc = os.path.join(mydir, 'tclass')
197 tc = os.path.join(mydir, 'tclass')
196 src = ("%%run '%s' C-first\n"
198 src = ("%%run '%s' C-first\n"
197 "%%run '%s' C-second\n"
199 "%%run '%s' C-second\n"
198 "%%run '%s' C-third\n") % (tc, tc, tc)
200 "%%run '%s' C-third\n") % (tc, tc, tc)
199 self.mktmp(src, '.ipy')
201 self.mktmp(src, '.ipy')
200 out = """\
202 out = """\
201 ARGV 1-: [u'C-first']
203 ARGV 1-: [u'C-first']
202 ARGV 1-: [u'C-second']
204 ARGV 1-: [u'C-second']
203 tclass.py: deleting object: C-first
205 tclass.py: deleting object: C-first
204 ARGV 1-: [u'C-third']
206 ARGV 1-: [u'C-third']
205 tclass.py: deleting object: C-second
207 tclass.py: deleting object: C-second
206 tclass.py: deleting object: C-third
208 tclass.py: deleting object: C-third
207 """
209 """
208 tt.ipexec_validate(self.fname, out)
210 tt.ipexec_validate(self.fname, out)
General Comments 0
You need to be logged in to leave comments. Login now