Show More
@@ -995,7 +995,6 b' class HelpHandler(PrefilterHandler):' | |||||
995 | # Pass any other exceptions through to the normal handler |
|
995 | # Pass any other exceptions through to the normal handler | |
996 | return normal_handler.handle(line_info) |
|
996 | return normal_handler.handle(line_info) | |
997 | else: |
|
997 | else: | |
998 | raise |
|
|||
999 | # If the code compiles ok, we should handle it normally |
|
998 | # If the code compiles ok, we should handle it normally | |
1000 | return normal_handler.handle(line_info) |
|
999 | return normal_handler.handle(line_info) | |
1001 |
|
1000 |
@@ -1,12 +1,41 b'' | |||||
1 | """Test the various handlers which do the actual rewriting of the line.""" |
|
1 | """Tests for input handlers. | |
|
2 | """ | |||
|
3 | #----------------------------------------------------------------------------- | |||
|
4 | # Module imports | |||
|
5 | #----------------------------------------------------------------------------- | |||
2 |
|
6 | |||
3 | from StringIO import StringIO |
|
7 | # third party | |
4 | import sys |
|
8 | import nose.tools as nt | |
5 | sys.path.append('..') |
|
9 | ||
|
10 | # our own packages | |||
|
11 | from IPython.core import autocall | |||
|
12 | from IPython.testing import decorators as dec | |||
|
13 | from IPython.testing.globalipapp import get_ipython | |||
|
14 | ||||
|
15 | #----------------------------------------------------------------------------- | |||
|
16 | # Globals | |||
|
17 | #----------------------------------------------------------------------------- | |||
|
18 | ||||
|
19 | # Get the public instance of IPython | |||
|
20 | ip = get_ipython() | |||
6 |
|
21 | |||
7 | failures = [] |
|
22 | failures = [] | |
8 | num_tests = 0 |
|
23 | num_tests = 0 | |
9 |
|
24 | |||
|
25 | #----------------------------------------------------------------------------- | |||
|
26 | # Test functions | |||
|
27 | #----------------------------------------------------------------------------- | |||
|
28 | ||||
|
29 | class CallableIndexable(object): | |||
|
30 | def __getitem__(self, idx): return True | |||
|
31 | def __call__(self, *args, **kws): return True | |||
|
32 | ||||
|
33 | ||||
|
34 | class Autocallable(autocall.IPyAutocall): | |||
|
35 | def __call__(self): | |||
|
36 | return "called" | |||
|
37 | ||||
|
38 | ||||
10 | def run(tests): |
|
39 | def run(tests): | |
11 | """Loop through a list of (pre, post) inputs, where pre is the string |
|
40 | """Loop through a list of (pre, post) inputs, where pre is the string | |
12 | handed to ipython, and post is how that string looks after it's been |
|
41 | handed to ipython, and post is how that string looks after it's been | |
@@ -24,87 +53,56 b' def run(tests):' | |||||
24 | pre, post, actual)) |
|
53 | pre, post, actual)) | |
25 |
|
54 | |||
26 |
|
55 | |||
27 | # Shutdown stdout/stderr so that ipython isn't noisy during tests. Have to |
|
56 | def test_handlers(): | |
28 | # do this *before* importing IPython below. |
|
|||
29 | # |
|
|||
30 | # NOTE: this means that, if you stick print statements into code as part of |
|
|||
31 | # debugging, you won't see the results (unless you comment out some of the |
|
|||
32 | # below). I keep on doing this, so apparently it's easy. Or I am an idiot. |
|
|||
33 | old_stdout = sys.stdout |
|
|||
34 | old_stderr = sys.stderr |
|
|||
35 |
|
||||
36 | sys.stdout = StringIO() |
|
|||
37 | sys.stderr = StringIO() |
|
|||
38 |
|
||||
39 | import IPython |
|
|||
40 | import IPython.ipapi |
|
|||
41 |
|
||||
42 | IPython.Shell.start() |
|
|||
43 | ip = IPython.ipapi.get() |
|
|||
44 |
|
||||
45 | class CallableIndexable(object): |
|
|||
46 | def __getitem__(self, idx): return True |
|
|||
47 | def __call__(self, *args, **kws): return True |
|
|||
48 |
|
||||
49 |
|
||||
50 | try: |
|
|||
51 | # alias expansion |
|
57 | # alias expansion | |
52 |
|
58 | |||
53 | # We're using 'true' as our syscall of choice because it doesn't |
|
59 | # We're using 'true' as our syscall of choice because it doesn't | |
54 | # write anything to stdout. |
|
60 | # write anything to stdout. | |
55 |
|
61 | |||
56 | # Turn off actual execution of aliases, because it's noisy |
|
62 | # Turn off actual execution of aliases, because it's noisy | |
57 | old_system_cmd = ip.system |
|
63 | old_system_cmd = ip.system | |
58 | ip.system = lambda cmd: None |
|
64 | ip.system = lambda cmd: None | |
59 |
|
65 | |||
60 |
|
66 | |||
61 |
ip. |
|
67 | ip.alias_manager.alias_table['an_alias'] = (0, 'true') | |
62 | # These are useful for checking a particular recursive alias issue |
|
68 | # These are useful for checking a particular recursive alias issue | |
63 |
ip. |
|
69 | ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') | |
64 |
ip. |
|
70 | ip.alias_manager.alias_table['d'] = (0, 'true') | |
65 | run([("an_alias", '_ip.system("true ")'), # alias |
|
71 | run([("an_alias", 'get_ipython().system("true ")'), # alias | |
66 | # Below: recursive aliases should expand whitespace-surrounded |
|
72 | # Below: recursive aliases should expand whitespace-surrounded | |
67 | # chars, *not* initial chars which happen to be aliases: |
|
73 | # chars, *not* initial chars which happen to be aliases: | |
68 | ("top", '_ip.system("d:/cygwin/top ")'), |
|
74 | ("top", 'get_ipython().system("d:/cygwin/top ")'), | |
69 | ]) |
|
75 | ]) | |
70 | ip.system = old_system_cmd |
|
76 | ip.system = old_system_cmd | |
71 |
|
77 | |||
72 |
|
||||
73 | call_idx = CallableIndexable() |
|
78 | call_idx = CallableIndexable() | |
74 |
ip. |
|
79 | ip.user_ns['call_idx'] = call_idx | |
75 |
|
80 | |||
76 | # For many of the below, we're also checking that leading whitespace |
|
81 | # For many of the below, we're also checking that leading whitespace | |
77 | # turns off the esc char, which it should unless there is a continuation |
|
82 | # turns off the esc char, which it should unless there is a continuation | |
78 | # line. |
|
83 | # line. | |
79 | run([('"no change"', '"no change"'), # normal |
|
84 | run([('"no change"', '"no change"'), # normal | |
80 | ("!true", '_ip.system("true")'), # shell_escapes |
|
85 | ("!true", 'get_ipython().system("true")'), # shell_escapes | |
81 | ("!! true", '_ip.magic("sx true")'), # shell_escapes + magic |
|
86 | ("!! true", 'get_ipython().magic("sx true")'), # shell_escapes + magic | |
82 | ("!!true", '_ip.magic("sx true")'), # shell_escapes + magic |
|
87 | ("!!true", 'get_ipython().magic("sx true")'), # shell_escapes + magic | |
83 | ("%lsmagic", '_ip.magic("lsmagic ")'), # magic |
|
88 | ("%lsmagic", 'get_ipython().magic("lsmagic ")'), # magic | |
84 | ("lsmagic", '_ip.magic("lsmagic ")'), # magic |
|
89 | ("lsmagic", 'get_ipython().magic("lsmagic ")'), # magic | |
85 | ("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache |
|
90 | #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache | |
86 |
|
91 | |||
87 | # post-esc-char whitespace goes inside |
|
92 | # post-esc-char whitespace goes inside | |
88 | ("! true", '_ip.system(" true")'), |
|
93 | ("! true", 'get_ipython().system(" true")'), | |
89 |
|
||||
90 | # Leading whitespace generally turns off escape characters |
|
|||
91 | (" ! true", ' ! true'), |
|
|||
92 | (" !true", ' !true'), |
|
|||
93 |
|
94 | |||
94 | # handle_help |
|
95 | # handle_help | |
95 |
|
96 | |||
96 | # These are weak tests -- just looking at what the help handlers |
|
97 | # These are weak tests -- just looking at what the help handlers | |
97 | # logs, which is not how it really does its work. But it still |
|
98 | # logs, which is not how it really does its work. But it still | |
98 | # lets us check the key paths through the handler. |
|
99 | # lets us check the key paths through the handler. | |
99 |
|
100 | |||
100 | ("x=1 # what?", "x=1 # what?"), # no help if valid python |
|
101 | ("x=1 # what?", "x=1 # what?"), # no help if valid python | |
101 | ("len?", "#?len"), # this is what help logs when it runs |
|
|||
102 | ("len??", "#?len?"), |
|
|||
103 | ("?len", "#?len"), |
|
|||
104 | ]) |
|
102 | ]) | |
105 |
|
103 | |||
106 | # multi_line_specials |
|
104 | # multi_line_specials | |
107 |
ip. |
|
105 | ip.prefilter_manager.multi_line_specials = False | |
108 | # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion |
|
106 | # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion | |
109 | run([ |
|
107 | run([ | |
110 | ('if 1:\n !true', 'if 1:\n !true'), |
|
108 | ('if 1:\n !true', 'if 1:\n !true'), | |
@@ -112,18 +110,16 b' try:' | |||||
112 | ('if 1:\n an_alias', 'if 1:\n an_alias'), |
|
110 | ('if 1:\n an_alias', 'if 1:\n an_alias'), | |
113 | ]) |
|
111 | ]) | |
114 |
|
112 | |||
115 |
ip. |
|
113 | ip.prefilter_manager.multi_line_specials = True | |
116 | # initial indents must be preserved. |
|
114 | # initial indents must be preserved. | |
117 | run([ |
|
115 | run([ | |
118 | ('if 1:\n !true', 'if 1:\n _ip.system("true")'), |
|
116 | ('if 1:\n !true', 'if 1:\n get_ipython().system("true")'), | |
119 |
('if |
|
117 | ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic("lsmagic ")'), | |
120 | ('if 1:\n an_alias', 'if 1:\n _ip.system("true ")'), |
|
118 | ('if 1:\n an_alias', 'if 1:\n get_ipython().system("true ")'), | |
121 | # Weird one |
|
119 | # Weird one | |
122 | ('if 1:\n !!true', 'if 1:\n _ip.magic("sx true")'), |
|
120 | ('if 1:\n !!true', 'if 1:\n get_ipython().magic("sx true")'), | |
123 |
|
||||
124 |
|
121 | |||
125 |
# Even with m_l_s on, a |
|
122 | # Even with m_l_s on, autocall is off even with special chars | |
126 | ('if 1:\n %lsmagic', 'if 1:\n %lsmagic'), |
|
|||
127 | ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), |
|
123 | ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), | |
128 | ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), |
|
124 | ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), | |
129 | ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), |
|
125 | ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), | |
@@ -131,18 +127,12 b' try:' | |||||
131 | # What about !! |
|
127 | # What about !! | |
132 | ]) |
|
128 | ]) | |
133 |
|
129 | |||
134 |
|
||||
135 | # Objects which are instances of IPyAutocall are *always* autocalled |
|
130 | # Objects which are instances of IPyAutocall are *always* autocalled | |
136 | import IPython.ipapi |
|
|||
137 | class Autocallable(IPython.ipapi.IPyAutocall): |
|
|||
138 | def __call__(self): |
|
|||
139 | return "called" |
|
|||
140 |
|
||||
141 | autocallable = Autocallable() |
|
131 | autocallable = Autocallable() | |
142 |
ip. |
|
132 | ip.user_ns['autocallable'] = autocallable | |
143 |
|
133 | |||
144 | # auto |
|
134 | # auto | |
145 |
ip. |
|
135 | ip.magic('autocall 0') | |
146 | # Only explicit escapes or instances of IPyAutocallable should get |
|
136 | # Only explicit escapes or instances of IPyAutocallable should get | |
147 | # expanded |
|
137 | # expanded | |
148 | run([ |
|
138 | run([ | |
@@ -152,7 +142,7 b' try:' | |||||
152 | (";list 1 2 3", 'list("1 2 3")'), |
|
142 | (";list 1 2 3", 'list("1 2 3")'), | |
153 | ("/len range(1,4)", 'len(range(1,4))'), |
|
143 | ("/len range(1,4)", 'len(range(1,4))'), | |
154 | ]) |
|
144 | ]) | |
155 |
ip. |
|
145 | ip.magic('autocall 1') | |
156 | run([ |
|
146 | run([ | |
157 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
147 | (",list 1 2 3", 'list("1", "2", "3")'), | |
158 | (";list 1 2 3", 'list("1 2 3")'), |
|
148 | (";list 1 2 3", 'list("1 2 3")'), | |
@@ -166,8 +156,7 b' try:' | |||||
166 | ('call_idx 1', 'call_idx(1)'), |
|
156 | ('call_idx 1', 'call_idx(1)'), | |
167 | ('len', 'len '), # only at 2 does it auto-call on single args |
|
157 | ('len', 'len '), # only at 2 does it auto-call on single args | |
168 | ]) |
|
158 | ]) | |
169 |
|
159 | ip.magic('autocall 2') | ||
170 | ip.options.autocall = 2 |
|
|||
171 | run([ |
|
160 | run([ | |
172 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
161 | (",list 1 2 3", 'list("1", "2", "3")'), | |
173 | (";list 1 2 3", 'list("1 2 3")'), |
|
162 | (";list 1 2 3", 'list("1 2 3")'), | |
@@ -180,23 +169,6 b' try:' | |||||
180 | # This is what's different: |
|
169 | # This is what's different: | |
181 | ('len', 'len()'), # only at 2 does it auto-call on single args |
|
170 | ('len', 'len()'), # only at 2 does it auto-call on single args | |
182 | ]) |
|
171 | ]) | |
183 |
ip. |
|
172 | ip.magic('autocall 1') | |
184 |
|
||||
185 | # Ignoring handle_emacs, 'cause it doesn't do anything. |
|
|||
186 | finally: |
|
|||
187 | sys.stdout = old_stdout |
|
|||
188 | sys.stderr = old_stderr |
|
|||
189 |
|
||||
190 |
|
||||
191 |
|
||||
192 |
|
||||
193 | num_f = len(failures) |
|
|||
194 | #if verbose: |
|
|||
195 |
|
||||
196 |
|
||||
197 |
|
173 | |||
198 | print "%s tests run, %s failure%s" % (num_tests, |
|
174 | nt.assert_equals(failures, []) | |
199 | num_f, |
|
|||
200 | num_f != 1 and "s" or "") |
|
|||
201 | for f in failures: |
|
|||
202 | print f |
|
General Comments 0
You need to be logged in to leave comments.
Login now