##// END OF EJS Templates
Merge pull request #8339 from takluyver/ascii-completions-test-cwd...
Matthias Bussonnier -
r21283:8a631498 merge
parent child Browse files
Show More
@@ -1,754 +1,755 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for the IPython tab-completion machinery."""
2 """Tests for the IPython tab-completion machinery."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import unittest
9 import unittest
10
10
11 from contextlib import contextmanager
11 from contextlib import contextmanager
12
12
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 from traitlets.config.loader import Config
15 from traitlets.config.loader import Config
16 from IPython.core import completer
16 from IPython.core import completer
17 from IPython.external.decorators import knownfailureif
17 from IPython.external.decorators import knownfailureif
18 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
18 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 from IPython.utils.generics import complete_object
19 from IPython.utils.generics import complete_object
20 from IPython.utils import py3compat
20 from IPython.utils import py3compat
21 from IPython.utils.py3compat import string_types, unicode_type
21 from IPython.utils.py3compat import string_types, unicode_type
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions
25 # Test functions
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @contextmanager
28 @contextmanager
29 def greedy_completion():
29 def greedy_completion():
30 ip = get_ipython()
30 ip = get_ipython()
31 greedy_original = ip.Completer.greedy
31 greedy_original = ip.Completer.greedy
32 try:
32 try:
33 ip.Completer.greedy = True
33 ip.Completer.greedy = True
34 yield
34 yield
35 finally:
35 finally:
36 ip.Completer.greedy = greedy_original
36 ip.Completer.greedy = greedy_original
37
37
38 def test_protect_filename():
38 def test_protect_filename():
39 pairs = [ ('abc','abc'),
39 pairs = [ ('abc','abc'),
40 (' abc',r'\ abc'),
40 (' abc',r'\ abc'),
41 ('a bc',r'a\ bc'),
41 ('a bc',r'a\ bc'),
42 ('a bc',r'a\ \ bc'),
42 ('a bc',r'a\ \ bc'),
43 (' bc',r'\ \ bc'),
43 (' bc',r'\ \ bc'),
44 ]
44 ]
45 # On posix, we also protect parens and other special characters
45 # On posix, we also protect parens and other special characters
46 if sys.platform != 'win32':
46 if sys.platform != 'win32':
47 pairs.extend( [('a(bc',r'a\(bc'),
47 pairs.extend( [('a(bc',r'a\(bc'),
48 ('a)bc',r'a\)bc'),
48 ('a)bc',r'a\)bc'),
49 ('a( )bc',r'a\(\ \)bc'),
49 ('a( )bc',r'a\(\ \)bc'),
50 ('a[1]bc', r'a\[1\]bc'),
50 ('a[1]bc', r'a\[1\]bc'),
51 ('a{1}bc', r'a\{1\}bc'),
51 ('a{1}bc', r'a\{1\}bc'),
52 ('a#bc', r'a\#bc'),
52 ('a#bc', r'a\#bc'),
53 ('a?bc', r'a\?bc'),
53 ('a?bc', r'a\?bc'),
54 ('a=bc', r'a\=bc'),
54 ('a=bc', r'a\=bc'),
55 ('a\\bc', r'a\\bc'),
55 ('a\\bc', r'a\\bc'),
56 ('a|bc', r'a\|bc'),
56 ('a|bc', r'a\|bc'),
57 ('a;bc', r'a\;bc'),
57 ('a;bc', r'a\;bc'),
58 ('a:bc', r'a\:bc'),
58 ('a:bc', r'a\:bc'),
59 ("a'bc", r"a\'bc"),
59 ("a'bc", r"a\'bc"),
60 ('a*bc', r'a\*bc'),
60 ('a*bc', r'a\*bc'),
61 ('a"bc', r'a\"bc'),
61 ('a"bc', r'a\"bc'),
62 ('a^bc', r'a\^bc'),
62 ('a^bc', r'a\^bc'),
63 ('a&bc', r'a\&bc'),
63 ('a&bc', r'a\&bc'),
64 ] )
64 ] )
65 # run the actual tests
65 # run the actual tests
66 for s1, s2 in pairs:
66 for s1, s2 in pairs:
67 s1p = completer.protect_filename(s1)
67 s1p = completer.protect_filename(s1)
68 nt.assert_equal(s1p, s2)
68 nt.assert_equal(s1p, s2)
69
69
70
70
71 def check_line_split(splitter, test_specs):
71 def check_line_split(splitter, test_specs):
72 for part1, part2, split in test_specs:
72 for part1, part2, split in test_specs:
73 cursor_pos = len(part1)
73 cursor_pos = len(part1)
74 line = part1+part2
74 line = part1+part2
75 out = splitter.split_line(line, cursor_pos)
75 out = splitter.split_line(line, cursor_pos)
76 nt.assert_equal(out, split)
76 nt.assert_equal(out, split)
77
77
78
78
79 def test_line_split():
79 def test_line_split():
80 """Basic line splitter test with default specs."""
80 """Basic line splitter test with default specs."""
81 sp = completer.CompletionSplitter()
81 sp = completer.CompletionSplitter()
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
84 # was at the end of part1. So an empty part2 represents someone hitting
84 # was at the end of part1. So an empty part2 represents someone hitting
85 # tab at the end of the line, the most common case.
85 # tab at the end of the line, the most common case.
86 t = [('run some/scrip', '', 'some/scrip'),
86 t = [('run some/scrip', '', 'some/scrip'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
88 ('echo $HOM', '', 'HOM'),
88 ('echo $HOM', '', 'HOM'),
89 ('print sys.pa', '', 'sys.pa'),
89 ('print sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
91 ("execfile('scripts/er", '', 'scripts/er'),
91 ("execfile('scripts/er", '', 'scripts/er'),
92 ('a[x.', '', 'x.'),
92 ('a[x.', '', 'x.'),
93 ('a[x.', 'y', 'x.'),
93 ('a[x.', 'y', 'x.'),
94 ('cd "some_file/', '', 'some_file/'),
94 ('cd "some_file/', '', 'some_file/'),
95 ]
95 ]
96 check_line_split(sp, t)
96 check_line_split(sp, t)
97 # Ensure splitting works OK with unicode by re-running the tests with
97 # Ensure splitting works OK with unicode by re-running the tests with
98 # all inputs turned into unicode
98 # all inputs turned into unicode
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
100
100
101
101
102 def test_custom_completion_error():
102 def test_custom_completion_error():
103 """Test that errors from custom attribute completers are silenced."""
103 """Test that errors from custom attribute completers are silenced."""
104 ip = get_ipython()
104 ip = get_ipython()
105 class A(object): pass
105 class A(object): pass
106 ip.user_ns['a'] = A()
106 ip.user_ns['a'] = A()
107
107
108 @complete_object.when_type(A)
108 @complete_object.when_type(A)
109 def complete_A(a, existing_completions):
109 def complete_A(a, existing_completions):
110 raise TypeError("this should be silenced")
110 raise TypeError("this should be silenced")
111
111
112 ip.complete("a.")
112 ip.complete("a.")
113
113
114
114
115 def test_unicode_completions():
115 def test_unicode_completions():
116 ip = get_ipython()
116 ip = get_ipython()
117 # Some strings that trigger different types of completion. Check them both
117 # Some strings that trigger different types of completion. Check them both
118 # in str and unicode forms
118 # in str and unicode forms
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
120 for t in s + list(map(unicode_type, s)):
120 for t in s + list(map(unicode_type, s)):
121 # We don't need to check exact completion values (they may change
121 # We don't need to check exact completion values (they may change
122 # depending on the state of the namespace, but at least no exceptions
122 # depending on the state of the namespace, but at least no exceptions
123 # should be thrown and the return value should be a pair of text, list
123 # should be thrown and the return value should be a pair of text, list
124 # values.
124 # values.
125 text, matches = ip.complete(t)
125 text, matches = ip.complete(t)
126 nt.assert_true(isinstance(text, string_types))
126 nt.assert_true(isinstance(text, string_types))
127 nt.assert_true(isinstance(matches, list))
127 nt.assert_true(isinstance(matches, list))
128
128
129 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
129 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
130 def test_latex_completions():
130 def test_latex_completions():
131 from IPython.core.latex_symbols import latex_symbols
131 from IPython.core.latex_symbols import latex_symbols
132 import random
132 import random
133 ip = get_ipython()
133 ip = get_ipython()
134 # Test some random unicode symbols
134 # Test some random unicode symbols
135 keys = random.sample(latex_symbols.keys(), 10)
135 keys = random.sample(latex_symbols.keys(), 10)
136 for k in keys:
136 for k in keys:
137 text, matches = ip.complete(k)
137 text, matches = ip.complete(k)
138 nt.assert_equal(len(matches),1)
138 nt.assert_equal(len(matches),1)
139 nt.assert_equal(text, k)
139 nt.assert_equal(text, k)
140 nt.assert_equal(matches[0], latex_symbols[k])
140 nt.assert_equal(matches[0], latex_symbols[k])
141 # Test a more complex line
141 # Test a more complex line
142 text, matches = ip.complete(u'print(\\alpha')
142 text, matches = ip.complete(u'print(\\alpha')
143 nt.assert_equals(text, u'\\alpha')
143 nt.assert_equals(text, u'\\alpha')
144 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
144 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
145 # Test multiple matching latex symbols
145 # Test multiple matching latex symbols
146 text, matches = ip.complete(u'\\al')
146 text, matches = ip.complete(u'\\al')
147 nt.assert_in('\\alpha', matches)
147 nt.assert_in('\\alpha', matches)
148 nt.assert_in('\\aleph', matches)
148 nt.assert_in('\\aleph', matches)
149
149
150
150
151
151
152
152
153 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
153 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
154 def test_back_latex_completion():
154 def test_back_latex_completion():
155 ip = get_ipython()
155 ip = get_ipython()
156
156
157 # do not return more than 1 matches fro \beta, only the latex one.
157 # do not return more than 1 matches fro \beta, only the latex one.
158 name, matches = ip.complete('\\Ξ²')
158 name, matches = ip.complete('\\Ξ²')
159 nt.assert_equal(len(matches), 1)
159 nt.assert_equal(len(matches), 1)
160 nt.assert_equal(matches[0], '\\beta')
160 nt.assert_equal(matches[0], '\\beta')
161
161
162 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
162 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
163 def test_back_unicode_completion():
163 def test_back_unicode_completion():
164 ip = get_ipython()
164 ip = get_ipython()
165
165
166 name, matches = ip.complete('\\β…€')
166 name, matches = ip.complete('\\β…€')
167 nt.assert_equal(len(matches), 1)
167 nt.assert_equal(len(matches), 1)
168 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
168 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
169
169
170
170
171 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
171 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
172 def test_forward_unicode_completion():
172 def test_forward_unicode_completion():
173 ip = get_ipython()
173 ip = get_ipython()
174
174
175 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
175 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
176 nt.assert_equal(len(matches), 1)
176 nt.assert_equal(len(matches), 1)
177 nt.assert_equal(matches[0], 'β…€')
177 nt.assert_equal(matches[0], 'β…€')
178
178
179 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
179 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
180 def test_no_ascii_back_completion():
180 def test_no_ascii_back_completion():
181 ip = get_ipython()
181 ip = get_ipython()
182 with TemporaryWorkingDirectory(): # Avoid any filename completions
182 # single ascii letter that don't have yet completions
183 # single ascii letter that don't have yet completions
183 for letter in 'fjqyJMQVWY' :
184 for letter in 'fjqyJMQVWY' :
184 name, matches = ip.complete('\\'+letter)
185 name, matches = ip.complete('\\'+letter)
185 nt.assert_equal(len(matches), 0)
186 nt.assert_equal(matches, [])
186
187
187
188
188
189
189
190
190 class CompletionSplitterTestCase(unittest.TestCase):
191 class CompletionSplitterTestCase(unittest.TestCase):
191 def setUp(self):
192 def setUp(self):
192 self.sp = completer.CompletionSplitter()
193 self.sp = completer.CompletionSplitter()
193
194
194 def test_delim_setting(self):
195 def test_delim_setting(self):
195 self.sp.delims = ' '
196 self.sp.delims = ' '
196 nt.assert_equal(self.sp.delims, ' ')
197 nt.assert_equal(self.sp.delims, ' ')
197 nt.assert_equal(self.sp._delim_expr, '[\ ]')
198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
198
199
199 def test_spaces(self):
200 def test_spaces(self):
200 """Test with only spaces as split chars."""
201 """Test with only spaces as split chars."""
201 self.sp.delims = ' '
202 self.sp.delims = ' '
202 t = [('foo', '', 'foo'),
203 t = [('foo', '', 'foo'),
203 ('run foo', '', 'foo'),
204 ('run foo', '', 'foo'),
204 ('run foo', 'bar', 'foo'),
205 ('run foo', 'bar', 'foo'),
205 ]
206 ]
206 check_line_split(self.sp, t)
207 check_line_split(self.sp, t)
207
208
208
209
209 def test_has_open_quotes1():
210 def test_has_open_quotes1():
210 for s in ["'", "'''", "'hi' '"]:
211 for s in ["'", "'''", "'hi' '"]:
211 nt.assert_equal(completer.has_open_quotes(s), "'")
212 nt.assert_equal(completer.has_open_quotes(s), "'")
212
213
213
214
214 def test_has_open_quotes2():
215 def test_has_open_quotes2():
215 for s in ['"', '"""', '"hi" "']:
216 for s in ['"', '"""', '"hi" "']:
216 nt.assert_equal(completer.has_open_quotes(s), '"')
217 nt.assert_equal(completer.has_open_quotes(s), '"')
217
218
218
219
219 def test_has_open_quotes3():
220 def test_has_open_quotes3():
220 for s in ["''", "''' '''", "'hi' 'ipython'"]:
221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
221 nt.assert_false(completer.has_open_quotes(s))
222 nt.assert_false(completer.has_open_quotes(s))
222
223
223
224
224 def test_has_open_quotes4():
225 def test_has_open_quotes4():
225 for s in ['""', '""" """', '"hi" "ipython"']:
226 for s in ['""', '""" """', '"hi" "ipython"']:
226 nt.assert_false(completer.has_open_quotes(s))
227 nt.assert_false(completer.has_open_quotes(s))
227
228
228
229
229 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
230 def test_abspath_file_completions():
231 def test_abspath_file_completions():
231 ip = get_ipython()
232 ip = get_ipython()
232 with TemporaryDirectory() as tmpdir:
233 with TemporaryDirectory() as tmpdir:
233 prefix = os.path.join(tmpdir, 'foo')
234 prefix = os.path.join(tmpdir, 'foo')
234 suffixes = ['1', '2']
235 suffixes = ['1', '2']
235 names = [prefix+s for s in suffixes]
236 names = [prefix+s for s in suffixes]
236 for n in names:
237 for n in names:
237 open(n, 'w').close()
238 open(n, 'w').close()
238
239
239 # Check simple completion
240 # Check simple completion
240 c = ip.complete(prefix)[1]
241 c = ip.complete(prefix)[1]
241 nt.assert_equal(c, names)
242 nt.assert_equal(c, names)
242
243
243 # Now check with a function call
244 # Now check with a function call
244 cmd = 'a = f("%s' % prefix
245 cmd = 'a = f("%s' % prefix
245 c = ip.complete(prefix, cmd)[1]
246 c = ip.complete(prefix, cmd)[1]
246 comp = [prefix+s for s in suffixes]
247 comp = [prefix+s for s in suffixes]
247 nt.assert_equal(c, comp)
248 nt.assert_equal(c, comp)
248
249
249
250
250 def test_local_file_completions():
251 def test_local_file_completions():
251 ip = get_ipython()
252 ip = get_ipython()
252 with TemporaryWorkingDirectory():
253 with TemporaryWorkingDirectory():
253 prefix = './foo'
254 prefix = './foo'
254 suffixes = ['1', '2']
255 suffixes = ['1', '2']
255 names = [prefix+s for s in suffixes]
256 names = [prefix+s for s in suffixes]
256 for n in names:
257 for n in names:
257 open(n, 'w').close()
258 open(n, 'w').close()
258
259
259 # Check simple completion
260 # Check simple completion
260 c = ip.complete(prefix)[1]
261 c = ip.complete(prefix)[1]
261 nt.assert_equal(c, names)
262 nt.assert_equal(c, names)
262
263
263 # Now check with a function call
264 # Now check with a function call
264 cmd = 'a = f("%s' % prefix
265 cmd = 'a = f("%s' % prefix
265 c = ip.complete(prefix, cmd)[1]
266 c = ip.complete(prefix, cmd)[1]
266 comp = [prefix+s for s in suffixes]
267 comp = [prefix+s for s in suffixes]
267 nt.assert_equal(c, comp)
268 nt.assert_equal(c, comp)
268
269
269
270
270 def test_greedy_completions():
271 def test_greedy_completions():
271 ip = get_ipython()
272 ip = get_ipython()
272 ip.ex('a=list(range(5))')
273 ip.ex('a=list(range(5))')
273 _,c = ip.complete('.',line='a[0].')
274 _,c = ip.complete('.',line='a[0].')
274 nt.assert_false('a[0].real' in c,
275 nt.assert_false('a[0].real' in c,
275 "Shouldn't have completed on a[0]: %s"%c)
276 "Shouldn't have completed on a[0]: %s"%c)
276 with greedy_completion():
277 with greedy_completion():
277 _,c = ip.complete('.',line='a[0].')
278 _,c = ip.complete('.',line='a[0].')
278 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
279 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
279
280
280
281
281 def test_omit__names():
282 def test_omit__names():
282 # also happens to test IPCompleter as a configurable
283 # also happens to test IPCompleter as a configurable
283 ip = get_ipython()
284 ip = get_ipython()
284 ip._hidden_attr = 1
285 ip._hidden_attr = 1
285 ip._x = {}
286 ip._x = {}
286 c = ip.Completer
287 c = ip.Completer
287 ip.ex('ip=get_ipython()')
288 ip.ex('ip=get_ipython()')
288 cfg = Config()
289 cfg = Config()
289 cfg.IPCompleter.omit__names = 0
290 cfg.IPCompleter.omit__names = 0
290 c.update_config(cfg)
291 c.update_config(cfg)
291 s,matches = c.complete('ip.')
292 s,matches = c.complete('ip.')
292 nt.assert_in('ip.__str__', matches)
293 nt.assert_in('ip.__str__', matches)
293 nt.assert_in('ip._hidden_attr', matches)
294 nt.assert_in('ip._hidden_attr', matches)
294 cfg.IPCompleter.omit__names = 1
295 cfg.IPCompleter.omit__names = 1
295 c.update_config(cfg)
296 c.update_config(cfg)
296 s,matches = c.complete('ip.')
297 s,matches = c.complete('ip.')
297 nt.assert_not_in('ip.__str__', matches)
298 nt.assert_not_in('ip.__str__', matches)
298 nt.assert_in('ip._hidden_attr', matches)
299 nt.assert_in('ip._hidden_attr', matches)
299 cfg.IPCompleter.omit__names = 2
300 cfg.IPCompleter.omit__names = 2
300 c.update_config(cfg)
301 c.update_config(cfg)
301 s,matches = c.complete('ip.')
302 s,matches = c.complete('ip.')
302 nt.assert_not_in('ip.__str__', matches)
303 nt.assert_not_in('ip.__str__', matches)
303 nt.assert_not_in('ip._hidden_attr', matches)
304 nt.assert_not_in('ip._hidden_attr', matches)
304 s,matches = c.complete('ip._x.')
305 s,matches = c.complete('ip._x.')
305 nt.assert_in('ip._x.keys', matches)
306 nt.assert_in('ip._x.keys', matches)
306 del ip._hidden_attr
307 del ip._hidden_attr
307
308
308
309
309 def test_limit_to__all__False_ok():
310 def test_limit_to__all__False_ok():
310 ip = get_ipython()
311 ip = get_ipython()
311 c = ip.Completer
312 c = ip.Completer
312 ip.ex('class D: x=24')
313 ip.ex('class D: x=24')
313 ip.ex('d=D()')
314 ip.ex('d=D()')
314 cfg = Config()
315 cfg = Config()
315 cfg.IPCompleter.limit_to__all__ = False
316 cfg.IPCompleter.limit_to__all__ = False
316 c.update_config(cfg)
317 c.update_config(cfg)
317 s, matches = c.complete('d.')
318 s, matches = c.complete('d.')
318 nt.assert_in('d.x', matches)
319 nt.assert_in('d.x', matches)
319
320
320
321
321 def test_limit_to__all__True_ok():
322 def test_limit_to__all__True_ok():
322 ip = get_ipython()
323 ip = get_ipython()
323 c = ip.Completer
324 c = ip.Completer
324 ip.ex('class D: x=24')
325 ip.ex('class D: x=24')
325 ip.ex('d=D()')
326 ip.ex('d=D()')
326 ip.ex("d.__all__=['z']")
327 ip.ex("d.__all__=['z']")
327 cfg = Config()
328 cfg = Config()
328 cfg.IPCompleter.limit_to__all__ = True
329 cfg.IPCompleter.limit_to__all__ = True
329 c.update_config(cfg)
330 c.update_config(cfg)
330 s, matches = c.complete('d.')
331 s, matches = c.complete('d.')
331 nt.assert_in('d.z', matches)
332 nt.assert_in('d.z', matches)
332 nt.assert_not_in('d.x', matches)
333 nt.assert_not_in('d.x', matches)
333
334
334
335
335 def test_get__all__entries_ok():
336 def test_get__all__entries_ok():
336 class A(object):
337 class A(object):
337 __all__ = ['x', 1]
338 __all__ = ['x', 1]
338 words = completer.get__all__entries(A())
339 words = completer.get__all__entries(A())
339 nt.assert_equal(words, ['x'])
340 nt.assert_equal(words, ['x'])
340
341
341
342
342 def test_get__all__entries_no__all__ok():
343 def test_get__all__entries_no__all__ok():
343 class A(object):
344 class A(object):
344 pass
345 pass
345 words = completer.get__all__entries(A())
346 words = completer.get__all__entries(A())
346 nt.assert_equal(words, [])
347 nt.assert_equal(words, [])
347
348
348
349
349 def test_func_kw_completions():
350 def test_func_kw_completions():
350 ip = get_ipython()
351 ip = get_ipython()
351 c = ip.Completer
352 c = ip.Completer
352 ip.ex('def myfunc(a=1,b=2): return a+b')
353 ip.ex('def myfunc(a=1,b=2): return a+b')
353 s, matches = c.complete(None, 'myfunc(1,b')
354 s, matches = c.complete(None, 'myfunc(1,b')
354 nt.assert_in('b=', matches)
355 nt.assert_in('b=', matches)
355 # Simulate completing with cursor right after b (pos==10):
356 # Simulate completing with cursor right after b (pos==10):
356 s, matches = c.complete(None, 'myfunc(1,b)', 10)
357 s, matches = c.complete(None, 'myfunc(1,b)', 10)
357 nt.assert_in('b=', matches)
358 nt.assert_in('b=', matches)
358 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
359 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
359 nt.assert_in('b=', matches)
360 nt.assert_in('b=', matches)
360 #builtin function
361 #builtin function
361 s, matches = c.complete(None, 'min(k, k')
362 s, matches = c.complete(None, 'min(k, k')
362 nt.assert_in('key=', matches)
363 nt.assert_in('key=', matches)
363
364
364
365
365 def test_default_arguments_from_docstring():
366 def test_default_arguments_from_docstring():
366 doc = min.__doc__
367 doc = min.__doc__
367 ip = get_ipython()
368 ip = get_ipython()
368 c = ip.Completer
369 c = ip.Completer
369 kwd = c._default_arguments_from_docstring(
370 kwd = c._default_arguments_from_docstring(
370 'min(iterable[, key=func]) -> value')
371 'min(iterable[, key=func]) -> value')
371 nt.assert_equal(kwd, ['key'])
372 nt.assert_equal(kwd, ['key'])
372 #with cython type etc
373 #with cython type etc
373 kwd = c._default_arguments_from_docstring(
374 kwd = c._default_arguments_from_docstring(
374 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
375 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
375 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
376 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
376 #white spaces
377 #white spaces
377 kwd = c._default_arguments_from_docstring(
378 kwd = c._default_arguments_from_docstring(
378 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
379 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
379 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
380 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
380
381
381 def test_line_magics():
382 def test_line_magics():
382 ip = get_ipython()
383 ip = get_ipython()
383 c = ip.Completer
384 c = ip.Completer
384 s, matches = c.complete(None, 'lsmag')
385 s, matches = c.complete(None, 'lsmag')
385 nt.assert_in('%lsmagic', matches)
386 nt.assert_in('%lsmagic', matches)
386 s, matches = c.complete(None, '%lsmag')
387 s, matches = c.complete(None, '%lsmag')
387 nt.assert_in('%lsmagic', matches)
388 nt.assert_in('%lsmagic', matches)
388
389
389
390
390 def test_cell_magics():
391 def test_cell_magics():
391 from IPython.core.magic import register_cell_magic
392 from IPython.core.magic import register_cell_magic
392
393
393 @register_cell_magic
394 @register_cell_magic
394 def _foo_cellm(line, cell):
395 def _foo_cellm(line, cell):
395 pass
396 pass
396
397
397 ip = get_ipython()
398 ip = get_ipython()
398 c = ip.Completer
399 c = ip.Completer
399
400
400 s, matches = c.complete(None, '_foo_ce')
401 s, matches = c.complete(None, '_foo_ce')
401 nt.assert_in('%%_foo_cellm', matches)
402 nt.assert_in('%%_foo_cellm', matches)
402 s, matches = c.complete(None, '%%_foo_ce')
403 s, matches = c.complete(None, '%%_foo_ce')
403 nt.assert_in('%%_foo_cellm', matches)
404 nt.assert_in('%%_foo_cellm', matches)
404
405
405
406
406 def test_line_cell_magics():
407 def test_line_cell_magics():
407 from IPython.core.magic import register_line_cell_magic
408 from IPython.core.magic import register_line_cell_magic
408
409
409 @register_line_cell_magic
410 @register_line_cell_magic
410 def _bar_cellm(line, cell):
411 def _bar_cellm(line, cell):
411 pass
412 pass
412
413
413 ip = get_ipython()
414 ip = get_ipython()
414 c = ip.Completer
415 c = ip.Completer
415
416
416 # The policy here is trickier, see comments in completion code. The
417 # The policy here is trickier, see comments in completion code. The
417 # returned values depend on whether the user passes %% or not explicitly,
418 # returned values depend on whether the user passes %% or not explicitly,
418 # and this will show a difference if the same name is both a line and cell
419 # and this will show a difference if the same name is both a line and cell
419 # magic.
420 # magic.
420 s, matches = c.complete(None, '_bar_ce')
421 s, matches = c.complete(None, '_bar_ce')
421 nt.assert_in('%_bar_cellm', matches)
422 nt.assert_in('%_bar_cellm', matches)
422 nt.assert_in('%%_bar_cellm', matches)
423 nt.assert_in('%%_bar_cellm', matches)
423 s, matches = c.complete(None, '%_bar_ce')
424 s, matches = c.complete(None, '%_bar_ce')
424 nt.assert_in('%_bar_cellm', matches)
425 nt.assert_in('%_bar_cellm', matches)
425 nt.assert_in('%%_bar_cellm', matches)
426 nt.assert_in('%%_bar_cellm', matches)
426 s, matches = c.complete(None, '%%_bar_ce')
427 s, matches = c.complete(None, '%%_bar_ce')
427 nt.assert_not_in('%_bar_cellm', matches)
428 nt.assert_not_in('%_bar_cellm', matches)
428 nt.assert_in('%%_bar_cellm', matches)
429 nt.assert_in('%%_bar_cellm', matches)
429
430
430
431
431 def test_magic_completion_order():
432 def test_magic_completion_order():
432
433
433 ip = get_ipython()
434 ip = get_ipython()
434 c = ip.Completer
435 c = ip.Completer
435
436
436 # Test ordering of magics and non-magics with the same name
437 # Test ordering of magics and non-magics with the same name
437 # We want the non-magic first
438 # We want the non-magic first
438
439
439 # Before importing matplotlib, there should only be one option:
440 # Before importing matplotlib, there should only be one option:
440
441
441 text, matches = c.complete('mat')
442 text, matches = c.complete('mat')
442 nt.assert_equal(matches, ["%matplotlib"])
443 nt.assert_equal(matches, ["%matplotlib"])
443
444
444
445
445 ip.run_cell("matplotlib = 1") # introduce name into namespace
446 ip.run_cell("matplotlib = 1") # introduce name into namespace
446
447
447 # After the import, there should be two options, ordered like this:
448 # After the import, there should be two options, ordered like this:
448 text, matches = c.complete('mat')
449 text, matches = c.complete('mat')
449 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
450 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
450
451
451
452
452 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
453 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
453
454
454 # Order of user variable and line and cell magics with same name:
455 # Order of user variable and line and cell magics with same name:
455 text, matches = c.complete('timeit')
456 text, matches = c.complete('timeit')
456 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
457 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
457
458
458
459
459 def test_dict_key_completion_string():
460 def test_dict_key_completion_string():
460 """Test dictionary key completion for string keys"""
461 """Test dictionary key completion for string keys"""
461 ip = get_ipython()
462 ip = get_ipython()
462 complete = ip.Completer.complete
463 complete = ip.Completer.complete
463
464
464 ip.user_ns['d'] = {'abc': None}
465 ip.user_ns['d'] = {'abc': None}
465
466
466 # check completion at different stages
467 # check completion at different stages
467 _, matches = complete(line_buffer="d[")
468 _, matches = complete(line_buffer="d[")
468 nt.assert_in("'abc'", matches)
469 nt.assert_in("'abc'", matches)
469 nt.assert_not_in("'abc']", matches)
470 nt.assert_not_in("'abc']", matches)
470
471
471 _, matches = complete(line_buffer="d['")
472 _, matches = complete(line_buffer="d['")
472 nt.assert_in("abc", matches)
473 nt.assert_in("abc", matches)
473 nt.assert_not_in("abc']", matches)
474 nt.assert_not_in("abc']", matches)
474
475
475 _, matches = complete(line_buffer="d['a")
476 _, matches = complete(line_buffer="d['a")
476 nt.assert_in("abc", matches)
477 nt.assert_in("abc", matches)
477 nt.assert_not_in("abc']", matches)
478 nt.assert_not_in("abc']", matches)
478
479
479 # check use of different quoting
480 # check use of different quoting
480 _, matches = complete(line_buffer="d[\"")
481 _, matches = complete(line_buffer="d[\"")
481 nt.assert_in("abc", matches)
482 nt.assert_in("abc", matches)
482 nt.assert_not_in('abc\"]', matches)
483 nt.assert_not_in('abc\"]', matches)
483
484
484 _, matches = complete(line_buffer="d[\"a")
485 _, matches = complete(line_buffer="d[\"a")
485 nt.assert_in("abc", matches)
486 nt.assert_in("abc", matches)
486 nt.assert_not_in('abc\"]', matches)
487 nt.assert_not_in('abc\"]', matches)
487
488
488 # check sensitivity to following context
489 # check sensitivity to following context
489 _, matches = complete(line_buffer="d[]", cursor_pos=2)
490 _, matches = complete(line_buffer="d[]", cursor_pos=2)
490 nt.assert_in("'abc'", matches)
491 nt.assert_in("'abc'", matches)
491
492
492 _, matches = complete(line_buffer="d['']", cursor_pos=3)
493 _, matches = complete(line_buffer="d['']", cursor_pos=3)
493 nt.assert_in("abc", matches)
494 nt.assert_in("abc", matches)
494 nt.assert_not_in("abc'", matches)
495 nt.assert_not_in("abc'", matches)
495 nt.assert_not_in("abc']", matches)
496 nt.assert_not_in("abc']", matches)
496
497
497 # check multiple solutions are correctly returned and that noise is not
498 # check multiple solutions are correctly returned and that noise is not
498 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
499 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
499 5: None}
500 5: None}
500
501
501 _, matches = complete(line_buffer="d['a")
502 _, matches = complete(line_buffer="d['a")
502 nt.assert_in("abc", matches)
503 nt.assert_in("abc", matches)
503 nt.assert_in("abd", matches)
504 nt.assert_in("abd", matches)
504 nt.assert_not_in("bad", matches)
505 nt.assert_not_in("bad", matches)
505 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
506 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
506
507
507 # check escaping and whitespace
508 # check escaping and whitespace
508 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
509 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
509 _, matches = complete(line_buffer="d['a")
510 _, matches = complete(line_buffer="d['a")
510 nt.assert_in("a\\nb", matches)
511 nt.assert_in("a\\nb", matches)
511 nt.assert_in("a\\'b", matches)
512 nt.assert_in("a\\'b", matches)
512 nt.assert_in("a\"b", matches)
513 nt.assert_in("a\"b", matches)
513 nt.assert_in("a word", matches)
514 nt.assert_in("a word", matches)
514 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
515 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
515
516
516 # - can complete on non-initial word of the string
517 # - can complete on non-initial word of the string
517 _, matches = complete(line_buffer="d['a w")
518 _, matches = complete(line_buffer="d['a w")
518 nt.assert_in("word", matches)
519 nt.assert_in("word", matches)
519
520
520 # - understands quote escaping
521 # - understands quote escaping
521 _, matches = complete(line_buffer="d['a\\'")
522 _, matches = complete(line_buffer="d['a\\'")
522 nt.assert_in("b", matches)
523 nt.assert_in("b", matches)
523
524
524 # - default quoting should work like repr
525 # - default quoting should work like repr
525 _, matches = complete(line_buffer="d[")
526 _, matches = complete(line_buffer="d[")
526 nt.assert_in("\"a'b\"", matches)
527 nt.assert_in("\"a'b\"", matches)
527
528
528 # - when opening quote with ", possible to match with unescaped apostrophe
529 # - when opening quote with ", possible to match with unescaped apostrophe
529 _, matches = complete(line_buffer="d[\"a'")
530 _, matches = complete(line_buffer="d[\"a'")
530 nt.assert_in("b", matches)
531 nt.assert_in("b", matches)
531
532
532
533
533 def test_dict_key_completion_contexts():
534 def test_dict_key_completion_contexts():
534 """Test expression contexts in which dict key completion occurs"""
535 """Test expression contexts in which dict key completion occurs"""
535 ip = get_ipython()
536 ip = get_ipython()
536 complete = ip.Completer.complete
537 complete = ip.Completer.complete
537 d = {'abc': None}
538 d = {'abc': None}
538 ip.user_ns['d'] = d
539 ip.user_ns['d'] = d
539
540
540 class C:
541 class C:
541 data = d
542 data = d
542 ip.user_ns['C'] = C
543 ip.user_ns['C'] = C
543 ip.user_ns['get'] = lambda: d
544 ip.user_ns['get'] = lambda: d
544
545
545 def assert_no_completion(**kwargs):
546 def assert_no_completion(**kwargs):
546 _, matches = complete(**kwargs)
547 _, matches = complete(**kwargs)
547 nt.assert_not_in('abc', matches)
548 nt.assert_not_in('abc', matches)
548 nt.assert_not_in('abc\'', matches)
549 nt.assert_not_in('abc\'', matches)
549 nt.assert_not_in('abc\']', matches)
550 nt.assert_not_in('abc\']', matches)
550 nt.assert_not_in('\'abc\'', matches)
551 nt.assert_not_in('\'abc\'', matches)
551 nt.assert_not_in('\'abc\']', matches)
552 nt.assert_not_in('\'abc\']', matches)
552
553
553 def assert_completion(**kwargs):
554 def assert_completion(**kwargs):
554 _, matches = complete(**kwargs)
555 _, matches = complete(**kwargs)
555 nt.assert_in("'abc'", matches)
556 nt.assert_in("'abc'", matches)
556 nt.assert_not_in("'abc']", matches)
557 nt.assert_not_in("'abc']", matches)
557
558
558 # no completion after string closed, even if reopened
559 # no completion after string closed, even if reopened
559 assert_no_completion(line_buffer="d['a'")
560 assert_no_completion(line_buffer="d['a'")
560 assert_no_completion(line_buffer="d[\"a\"")
561 assert_no_completion(line_buffer="d[\"a\"")
561 assert_no_completion(line_buffer="d['a' + ")
562 assert_no_completion(line_buffer="d['a' + ")
562 assert_no_completion(line_buffer="d['a' + '")
563 assert_no_completion(line_buffer="d['a' + '")
563
564
564 # completion in non-trivial expressions
565 # completion in non-trivial expressions
565 assert_completion(line_buffer="+ d[")
566 assert_completion(line_buffer="+ d[")
566 assert_completion(line_buffer="(d[")
567 assert_completion(line_buffer="(d[")
567 assert_completion(line_buffer="C.data[")
568 assert_completion(line_buffer="C.data[")
568
569
569 # greedy flag
570 # greedy flag
570 def assert_completion(**kwargs):
571 def assert_completion(**kwargs):
571 _, matches = complete(**kwargs)
572 _, matches = complete(**kwargs)
572 nt.assert_in("get()['abc']", matches)
573 nt.assert_in("get()['abc']", matches)
573
574
574 assert_no_completion(line_buffer="get()[")
575 assert_no_completion(line_buffer="get()[")
575 with greedy_completion():
576 with greedy_completion():
576 assert_completion(line_buffer="get()[")
577 assert_completion(line_buffer="get()[")
577 assert_completion(line_buffer="get()['")
578 assert_completion(line_buffer="get()['")
578 assert_completion(line_buffer="get()['a")
579 assert_completion(line_buffer="get()['a")
579 assert_completion(line_buffer="get()['ab")
580 assert_completion(line_buffer="get()['ab")
580 assert_completion(line_buffer="get()['abc")
581 assert_completion(line_buffer="get()['abc")
581
582
582
583
583
584
584 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
585 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
585 def test_dict_key_completion_bytes():
586 def test_dict_key_completion_bytes():
586 """Test handling of bytes in dict key completion"""
587 """Test handling of bytes in dict key completion"""
587 ip = get_ipython()
588 ip = get_ipython()
588 complete = ip.Completer.complete
589 complete = ip.Completer.complete
589
590
590 ip.user_ns['d'] = {'abc': None, b'abd': None}
591 ip.user_ns['d'] = {'abc': None, b'abd': None}
591
592
592 _, matches = complete(line_buffer="d[")
593 _, matches = complete(line_buffer="d[")
593 nt.assert_in("'abc'", matches)
594 nt.assert_in("'abc'", matches)
594 nt.assert_in("b'abd'", matches)
595 nt.assert_in("b'abd'", matches)
595
596
596 if False: # not currently implemented
597 if False: # not currently implemented
597 _, matches = complete(line_buffer="d[b")
598 _, matches = complete(line_buffer="d[b")
598 nt.assert_in("b'abd'", matches)
599 nt.assert_in("b'abd'", matches)
599 nt.assert_not_in("b'abc'", matches)
600 nt.assert_not_in("b'abc'", matches)
600
601
601 _, matches = complete(line_buffer="d[b'")
602 _, matches = complete(line_buffer="d[b'")
602 nt.assert_in("abd", matches)
603 nt.assert_in("abd", matches)
603 nt.assert_not_in("abc", matches)
604 nt.assert_not_in("abc", matches)
604
605
605 _, matches = complete(line_buffer="d[B'")
606 _, matches = complete(line_buffer="d[B'")
606 nt.assert_in("abd", matches)
607 nt.assert_in("abd", matches)
607 nt.assert_not_in("abc", matches)
608 nt.assert_not_in("abc", matches)
608
609
609 _, matches = complete(line_buffer="d['")
610 _, matches = complete(line_buffer="d['")
610 nt.assert_in("abc", matches)
611 nt.assert_in("abc", matches)
611 nt.assert_not_in("abd", matches)
612 nt.assert_not_in("abd", matches)
612
613
613
614
614 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
615 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
615 def test_dict_key_completion_unicode_py2():
616 def test_dict_key_completion_unicode_py2():
616 """Test handling of unicode in dict key completion"""
617 """Test handling of unicode in dict key completion"""
617 ip = get_ipython()
618 ip = get_ipython()
618 complete = ip.Completer.complete
619 complete = ip.Completer.complete
619
620
620 ip.user_ns['d'] = {u'abc': None,
621 ip.user_ns['d'] = {u'abc': None,
621 u'a\u05d0b': None}
622 u'a\u05d0b': None}
622
623
623 _, matches = complete(line_buffer="d[")
624 _, matches = complete(line_buffer="d[")
624 nt.assert_in("u'abc'", matches)
625 nt.assert_in("u'abc'", matches)
625 nt.assert_in("u'a\\u05d0b'", matches)
626 nt.assert_in("u'a\\u05d0b'", matches)
626
627
627 _, matches = complete(line_buffer="d['a")
628 _, matches = complete(line_buffer="d['a")
628 nt.assert_in("abc", matches)
629 nt.assert_in("abc", matches)
629 nt.assert_not_in("a\\u05d0b", matches)
630 nt.assert_not_in("a\\u05d0b", matches)
630
631
631 _, matches = complete(line_buffer="d[u'a")
632 _, matches = complete(line_buffer="d[u'a")
632 nt.assert_in("abc", matches)
633 nt.assert_in("abc", matches)
633 nt.assert_in("a\\u05d0b", matches)
634 nt.assert_in("a\\u05d0b", matches)
634
635
635 _, matches = complete(line_buffer="d[U'a")
636 _, matches = complete(line_buffer="d[U'a")
636 nt.assert_in("abc", matches)
637 nt.assert_in("abc", matches)
637 nt.assert_in("a\\u05d0b", matches)
638 nt.assert_in("a\\u05d0b", matches)
638
639
639 # query using escape
640 # query using escape
640 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
641 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
641 nt.assert_in("u05d0b", matches) # tokenized after \\
642 nt.assert_in("u05d0b", matches) # tokenized after \\
642
643
643 # query using character
644 # query using character
644 _, matches = complete(line_buffer=u"d[u'a\u05d0")
645 _, matches = complete(line_buffer=u"d[u'a\u05d0")
645 nt.assert_in(u"a\u05d0b", matches)
646 nt.assert_in(u"a\u05d0b", matches)
646
647
647 with greedy_completion():
648 with greedy_completion():
648 _, matches = complete(line_buffer="d[")
649 _, matches = complete(line_buffer="d[")
649 nt.assert_in("d[u'abc']", matches)
650 nt.assert_in("d[u'abc']", matches)
650 nt.assert_in("d[u'a\\u05d0b']", matches)
651 nt.assert_in("d[u'a\\u05d0b']", matches)
651
652
652 _, matches = complete(line_buffer="d['a")
653 _, matches = complete(line_buffer="d['a")
653 nt.assert_in("d['abc']", matches)
654 nt.assert_in("d['abc']", matches)
654 nt.assert_not_in("d[u'a\\u05d0b']", matches)
655 nt.assert_not_in("d[u'a\\u05d0b']", matches)
655
656
656 _, matches = complete(line_buffer="d[u'a")
657 _, matches = complete(line_buffer="d[u'a")
657 nt.assert_in("d[u'abc']", matches)
658 nt.assert_in("d[u'abc']", matches)
658 nt.assert_in("d[u'a\\u05d0b']", matches)
659 nt.assert_in("d[u'a\\u05d0b']", matches)
659
660
660 _, matches = complete(line_buffer="d[U'a")
661 _, matches = complete(line_buffer="d[U'a")
661 nt.assert_in("d[U'abc']", matches)
662 nt.assert_in("d[U'abc']", matches)
662 nt.assert_in("d[U'a\\u05d0b']", matches)
663 nt.assert_in("d[U'a\\u05d0b']", matches)
663
664
664 # query using escape
665 # query using escape
665 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
666 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
666 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
667 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
667
668
668 # query using character
669 # query using character
669 _, matches = complete(line_buffer=u"d[u'a\u05d0")
670 _, matches = complete(line_buffer=u"d[u'a\u05d0")
670 nt.assert_in(u"d[u'a\u05d0b']", matches)
671 nt.assert_in(u"d[u'a\u05d0b']", matches)
671
672
672
673
673 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
674 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
674 def test_dict_key_completion_unicode_py3():
675 def test_dict_key_completion_unicode_py3():
675 """Test handling of unicode in dict key completion"""
676 """Test handling of unicode in dict key completion"""
676 ip = get_ipython()
677 ip = get_ipython()
677 complete = ip.Completer.complete
678 complete = ip.Completer.complete
678
679
679 ip.user_ns['d'] = {u'a\u05d0': None}
680 ip.user_ns['d'] = {u'a\u05d0': None}
680
681
681 # query using escape
682 # query using escape
682 _, matches = complete(line_buffer="d['a\\u05d0")
683 _, matches = complete(line_buffer="d['a\\u05d0")
683 nt.assert_in("u05d0", matches) # tokenized after \\
684 nt.assert_in("u05d0", matches) # tokenized after \\
684
685
685 # query using character
686 # query using character
686 _, matches = complete(line_buffer="d['a\u05d0")
687 _, matches = complete(line_buffer="d['a\u05d0")
687 nt.assert_in(u"a\u05d0", matches)
688 nt.assert_in(u"a\u05d0", matches)
688
689
689 with greedy_completion():
690 with greedy_completion():
690 # query using escape
691 # query using escape
691 _, matches = complete(line_buffer="d['a\\u05d0")
692 _, matches = complete(line_buffer="d['a\\u05d0")
692 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
693 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
693
694
694 # query using character
695 # query using character
695 _, matches = complete(line_buffer="d['a\u05d0")
696 _, matches = complete(line_buffer="d['a\u05d0")
696 nt.assert_in(u"d['a\u05d0']", matches)
697 nt.assert_in(u"d['a\u05d0']", matches)
697
698
698
699
699
700
700 @dec.skip_without('numpy')
701 @dec.skip_without('numpy')
701 def test_struct_array_key_completion():
702 def test_struct_array_key_completion():
702 """Test dict key completion applies to numpy struct arrays"""
703 """Test dict key completion applies to numpy struct arrays"""
703 import numpy
704 import numpy
704 ip = get_ipython()
705 ip = get_ipython()
705 complete = ip.Completer.complete
706 complete = ip.Completer.complete
706 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
707 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
707 _, matches = complete(line_buffer="d['")
708 _, matches = complete(line_buffer="d['")
708 nt.assert_in("hello", matches)
709 nt.assert_in("hello", matches)
709 nt.assert_in("world", matches)
710 nt.assert_in("world", matches)
710 # complete on the numpy struct itself
711 # complete on the numpy struct itself
711 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
712 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
712 ('my_data', '>f4', 5)])
713 ('my_data', '>f4', 5)])
713 x = numpy.zeros(2, dtype=dt)
714 x = numpy.zeros(2, dtype=dt)
714 ip.user_ns['d'] = x[1]
715 ip.user_ns['d'] = x[1]
715 _, matches = complete(line_buffer="d['")
716 _, matches = complete(line_buffer="d['")
716 nt.assert_in("my_head", matches)
717 nt.assert_in("my_head", matches)
717 nt.assert_in("my_data", matches)
718 nt.assert_in("my_data", matches)
718 # complete on a nested level
719 # complete on a nested level
719 with greedy_completion():
720 with greedy_completion():
720 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
721 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
721 _, matches = complete(line_buffer="d[1]['my_head']['")
722 _, matches = complete(line_buffer="d[1]['my_head']['")
722 nt.assert_true(any(["my_dt" in m for m in matches]))
723 nt.assert_true(any(["my_dt" in m for m in matches]))
723 nt.assert_true(any(["my_df" in m for m in matches]))
724 nt.assert_true(any(["my_df" in m for m in matches]))
724
725
725
726
726 @dec.skip_without('pandas')
727 @dec.skip_without('pandas')
727 def test_dataframe_key_completion():
728 def test_dataframe_key_completion():
728 """Test dict key completion applies to pandas DataFrames"""
729 """Test dict key completion applies to pandas DataFrames"""
729 import pandas
730 import pandas
730 ip = get_ipython()
731 ip = get_ipython()
731 complete = ip.Completer.complete
732 complete = ip.Completer.complete
732 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
733 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
733 _, matches = complete(line_buffer="d['")
734 _, matches = complete(line_buffer="d['")
734 nt.assert_in("hello", matches)
735 nt.assert_in("hello", matches)
735 nt.assert_in("world", matches)
736 nt.assert_in("world", matches)
736
737
737
738
738 def test_dict_key_completion_invalids():
739 def test_dict_key_completion_invalids():
739 """Smoke test cases dict key completion can't handle"""
740 """Smoke test cases dict key completion can't handle"""
740 ip = get_ipython()
741 ip = get_ipython()
741 complete = ip.Completer.complete
742 complete = ip.Completer.complete
742
743
743 ip.user_ns['no_getitem'] = None
744 ip.user_ns['no_getitem'] = None
744 ip.user_ns['no_keys'] = []
745 ip.user_ns['no_keys'] = []
745 ip.user_ns['cant_call_keys'] = dict
746 ip.user_ns['cant_call_keys'] = dict
746 ip.user_ns['empty'] = {}
747 ip.user_ns['empty'] = {}
747 ip.user_ns['d'] = {'abc': 5}
748 ip.user_ns['d'] = {'abc': 5}
748
749
749 _, matches = complete(line_buffer="no_getitem['")
750 _, matches = complete(line_buffer="no_getitem['")
750 _, matches = complete(line_buffer="no_keys['")
751 _, matches = complete(line_buffer="no_keys['")
751 _, matches = complete(line_buffer="cant_call_keys['")
752 _, matches = complete(line_buffer="cant_call_keys['")
752 _, matches = complete(line_buffer="empty['")
753 _, matches = complete(line_buffer="empty['")
753 _, matches = complete(line_buffer="name_error['")
754 _, matches = complete(line_buffer="name_error['")
754 _, matches = complete(line_buffer="d['\\") # incomplete escape
755 _, matches = complete(line_buffer="d['\\") # incomplete escape
General Comments 0
You need to be logged in to leave comments. Login now