Show More
@@ -995,7 +995,6 b' class HelpHandler(PrefilterHandler):' | |||
|
995 | 995 | # Pass any other exceptions through to the normal handler |
|
996 | 996 | return normal_handler.handle(line_info) |
|
997 | 997 | else: |
|
998 | raise | |
|
999 | 998 | # If the code compiles ok, we should handle it normally |
|
1000 | 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 | |
|
4 | import sys | |
|
5 | sys.path.append('..') | |
|
7 | # third party | |
|
8 | import nose.tools as nt | |
|
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 | 22 | failures = [] |
|
8 | 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 | 39 | def run(tests): |
|
11 | 40 | """Loop through a list of (pre, post) inputs, where pre is the string |
|
12 | 41 | handed to ipython, and post is how that string looks after it's been |
@@ -24,87 +53,56 b' def run(tests):' | |||
|
24 | 53 | pre, post, actual)) |
|
25 | 54 | |
|
26 | 55 | |
|
27 | # Shutdown stdout/stderr so that ipython isn't noisy during tests. Have to | |
|
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: | |
|
56 | def test_handlers(): | |
|
51 | 57 | # alias expansion |
|
52 | ||
|
58 | ||
|
53 | 59 | # We're using 'true' as our syscall of choice because it doesn't |
|
54 | 60 | # write anything to stdout. |
|
55 | 61 | |
|
56 | 62 | # Turn off actual execution of aliases, because it's noisy |
|
57 | 63 | old_system_cmd = ip.system |
|
58 | 64 | ip.system = lambda cmd: None |
|
59 | ||
|
60 | ||
|
61 |
ip. |
|
|
65 | ||
|
66 | ||
|
67 | ip.alias_manager.alias_table['an_alias'] = (0, 'true') | |
|
62 | 68 | # These are useful for checking a particular recursive alias issue |
|
63 |
ip. |
|
|
64 |
ip. |
|
|
65 | run([("an_alias", '_ip.system("true ")'), # alias | |
|
69 | ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') | |
|
70 | ip.alias_manager.alias_table['d'] = (0, 'true') | |
|
71 | run([("an_alias", 'get_ipython().system("true ")'), # alias | |
|
66 | 72 | # Below: recursive aliases should expand whitespace-surrounded |
|
67 | 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 | 76 | ip.system = old_system_cmd |
|
71 | 77 | |
|
72 | ||
|
73 | 78 | call_idx = CallableIndexable() |
|
74 |
ip. |
|
|
79 | ip.user_ns['call_idx'] = call_idx | |
|
75 | 80 | |
|
76 | 81 | # For many of the below, we're also checking that leading whitespace |
|
77 | 82 | # turns off the esc char, which it should unless there is a continuation |
|
78 | 83 | # line. |
|
79 | 84 | run([('"no change"', '"no change"'), # normal |
|
80 | ("!true", '_ip.system("true")'), # shell_escapes | |
|
81 | ("!! true", '_ip.magic("sx true")'), # shell_escapes + magic | |
|
82 | ("!!true", '_ip.magic("sx true")'), # shell_escapes + magic | |
|
83 | ("%lsmagic", '_ip.magic("lsmagic ")'), # magic | |
|
84 | ("lsmagic", '_ip.magic("lsmagic ")'), # magic | |
|
85 | ("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache | |
|
85 | ("!true", 'get_ipython().system("true")'), # shell_escapes | |
|
86 | ("!! true", 'get_ipython().magic("sx true")'), # shell_escapes + magic | |
|
87 | ("!!true", 'get_ipython().magic("sx true")'), # shell_escapes + magic | |
|
88 | ("%lsmagic", 'get_ipython().magic("lsmagic ")'), # magic | |
|
89 | ("lsmagic", 'get_ipython().magic("lsmagic ")'), # magic | |
|
90 | #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache | |
|
86 | 91 | |
|
87 | 92 | # post-esc-char whitespace goes inside |
|
88 | ("! true", '_ip.system(" true")'), | |
|
89 | ||
|
90 | # Leading whitespace generally turns off escape characters | |
|
91 | (" ! true", ' ! true'), | |
|
92 | (" !true", ' !true'), | |
|
93 | ("! true", 'get_ipython().system(" true")'), | |
|
93 | 94 | |
|
94 | 95 | # handle_help |
|
95 | 96 | |
|
96 | 97 | # These are weak tests -- just looking at what the help handlers |
|
97 | 98 | # logs, which is not how it really does its work. But it still |
|
98 | 99 | # lets us check the key paths through the handler. |
|
99 | ||
|
100 | ||
|
100 | 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 | 104 | # multi_line_specials |
|
107 |
ip. |
|
|
105 | ip.prefilter_manager.multi_line_specials = False | |
|
108 | 106 | # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion |
|
109 | 107 | run([ |
|
110 | 108 | ('if 1:\n !true', 'if 1:\n !true'), |
@@ -112,18 +110,16 b' try:' | |||
|
112 | 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 | 114 | # initial indents must be preserved. |
|
117 | 115 | run([ |
|
118 | ('if 1:\n !true', 'if 1:\n _ip.system("true")'), | |
|
119 |
('if |
|
|
120 | ('if 1:\n an_alias', 'if 1:\n _ip.system("true ")'), | |
|
116 | ('if 1:\n !true', 'if 1:\n get_ipython().system("true")'), | |
|
117 | ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic("lsmagic ")'), | |
|
118 | ('if 1:\n an_alias', 'if 1:\n get_ipython().system("true ")'), | |
|
121 | 119 | # Weird one |
|
122 | ('if 1:\n !!true', 'if 1:\n _ip.magic("sx true")'), | |
|
123 | ||
|
120 | ('if 1:\n !!true', 'if 1:\n get_ipython().magic("sx true")'), | |
|
124 | 121 | |
|
125 |
# Even with m_l_s on, a |
|
|
126 | ('if 1:\n %lsmagic', 'if 1:\n %lsmagic'), | |
|
122 | # Even with m_l_s on, autocall is off even with special chars | |
|
127 | 123 | ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), |
|
128 | 124 | ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), |
|
129 | 125 | ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), |
@@ -131,18 +127,12 b' try:' | |||
|
131 | 127 | # What about !! |
|
132 | 128 | ]) |
|
133 | 129 | |
|
134 | ||
|
135 | 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 | 131 | autocallable = Autocallable() |
|
142 |
ip. |
|
|
132 | ip.user_ns['autocallable'] = autocallable | |
|
143 | 133 | |
|
144 | 134 | # auto |
|
145 |
ip. |
|
|
135 | ip.magic('autocall 0') | |
|
146 | 136 | # Only explicit escapes or instances of IPyAutocallable should get |
|
147 | 137 | # expanded |
|
148 | 138 | run([ |
@@ -152,7 +142,7 b' try:' | |||
|
152 | 142 | (";list 1 2 3", 'list("1 2 3")'), |
|
153 | 143 | ("/len range(1,4)", 'len(range(1,4))'), |
|
154 | 144 | ]) |
|
155 |
ip. |
|
|
145 | ip.magic('autocall 1') | |
|
156 | 146 | run([ |
|
157 | 147 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
158 | 148 | (";list 1 2 3", 'list("1 2 3")'), |
@@ -166,8 +156,7 b' try:' | |||
|
166 | 156 | ('call_idx 1', 'call_idx(1)'), |
|
167 | 157 | ('len', 'len '), # only at 2 does it auto-call on single args |
|
168 | 158 | ]) |
|
169 | ||
|
170 | ip.options.autocall = 2 | |
|
159 | ip.magic('autocall 2') | |
|
171 | 160 | run([ |
|
172 | 161 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
173 | 162 | (";list 1 2 3", 'list("1 2 3")'), |
@@ -180,23 +169,6 b' try:' | |||
|
180 | 169 | # This is what's different: |
|
181 | 170 | ('len', 'len()'), # only at 2 does it auto-call on single args |
|
182 | 171 | ]) |
|
183 |
ip. |
|
|
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 | ||
|
172 | ip.magic('autocall 1') | |
|
197 | 173 | |
|
198 | print "%s tests run, %s failure%s" % (num_tests, | |
|
199 | num_f, | |
|
200 | num_f != 1 and "s" or "") | |
|
201 | for f in failures: | |
|
202 | print f | |
|
174 | nt.assert_equals(failures, []) |
General Comments 0
You need to be logged in to leave comments.
Login now