##// END OF EJS Templates
Add completion tests.
Matthias Bussonnier -
Show More
@@ -1,796 +1,803 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 import get_ipython
16 from IPython import get_ipython
17 from IPython.core import completer
17 from IPython.core import completer
18 from IPython.external.decorators import knownfailureif
18 from IPython.external.decorators import knownfailureif
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 from IPython.utils.generics import complete_object
20 from IPython.utils.generics import complete_object
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 with TemporaryWorkingDirectory(): # Avoid any filename completions
183 # single ascii letter that don't have yet completions
183 # single ascii letter that don't have yet completions
184 for letter in 'fjqyJMQVWY' :
184 for letter in 'fjqyJMQVWY' :
185 name, matches = ip.complete('\\'+letter)
185 name, matches = ip.complete('\\'+letter)
186 nt.assert_equal(matches, [])
186 nt.assert_equal(matches, [])
187
187
188
188
189
189
190
190
191 class CompletionSplitterTestCase(unittest.TestCase):
191 class CompletionSplitterTestCase(unittest.TestCase):
192 def setUp(self):
192 def setUp(self):
193 self.sp = completer.CompletionSplitter()
193 self.sp = completer.CompletionSplitter()
194
194
195 def test_delim_setting(self):
195 def test_delim_setting(self):
196 self.sp.delims = ' '
196 self.sp.delims = ' '
197 nt.assert_equal(self.sp.delims, ' ')
197 nt.assert_equal(self.sp.delims, ' ')
198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
199
199
200 def test_spaces(self):
200 def test_spaces(self):
201 """Test with only spaces as split chars."""
201 """Test with only spaces as split chars."""
202 self.sp.delims = ' '
202 self.sp.delims = ' '
203 t = [('foo', '', 'foo'),
203 t = [('foo', '', 'foo'),
204 ('run foo', '', 'foo'),
204 ('run foo', '', 'foo'),
205 ('run foo', 'bar', 'foo'),
205 ('run foo', 'bar', 'foo'),
206 ]
206 ]
207 check_line_split(self.sp, t)
207 check_line_split(self.sp, t)
208
208
209
209
210 def test_has_open_quotes1():
210 def test_has_open_quotes1():
211 for s in ["'", "'''", "'hi' '"]:
211 for s in ["'", "'''", "'hi' '"]:
212 nt.assert_equal(completer.has_open_quotes(s), "'")
212 nt.assert_equal(completer.has_open_quotes(s), "'")
213
213
214
214
215 def test_has_open_quotes2():
215 def test_has_open_quotes2():
216 for s in ['"', '"""', '"hi" "']:
216 for s in ['"', '"""', '"hi" "']:
217 nt.assert_equal(completer.has_open_quotes(s), '"')
217 nt.assert_equal(completer.has_open_quotes(s), '"')
218
218
219
219
220 def test_has_open_quotes3():
220 def test_has_open_quotes3():
221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
222 nt.assert_false(completer.has_open_quotes(s))
222 nt.assert_false(completer.has_open_quotes(s))
223
223
224
224
225 def test_has_open_quotes4():
225 def test_has_open_quotes4():
226 for s in ['""', '""" """', '"hi" "ipython"']:
226 for s in ['""', '""" """', '"hi" "ipython"']:
227 nt.assert_false(completer.has_open_quotes(s))
227 nt.assert_false(completer.has_open_quotes(s))
228
228
229
229
230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
231 def test_abspath_file_completions():
231 def test_abspath_file_completions():
232 ip = get_ipython()
232 ip = get_ipython()
233 with TemporaryDirectory() as tmpdir:
233 with TemporaryDirectory() as tmpdir:
234 prefix = os.path.join(tmpdir, 'foo')
234 prefix = os.path.join(tmpdir, 'foo')
235 suffixes = ['1', '2']
235 suffixes = ['1', '2']
236 names = [prefix+s for s in suffixes]
236 names = [prefix+s for s in suffixes]
237 for n in names:
237 for n in names:
238 open(n, 'w').close()
238 open(n, 'w').close()
239
239
240 # Check simple completion
240 # Check simple completion
241 c = ip.complete(prefix)[1]
241 c = ip.complete(prefix)[1]
242 nt.assert_equal(c, names)
242 nt.assert_equal(c, names)
243
243
244 # Now check with a function call
244 # Now check with a function call
245 cmd = 'a = f("%s' % prefix
245 cmd = 'a = f("%s' % prefix
246 c = ip.complete(prefix, cmd)[1]
246 c = ip.complete(prefix, cmd)[1]
247 comp = [prefix+s for s in suffixes]
247 comp = [prefix+s for s in suffixes]
248 nt.assert_equal(c, comp)
248 nt.assert_equal(c, comp)
249
249
250
250
251 def test_local_file_completions():
251 def test_local_file_completions():
252 ip = get_ipython()
252 ip = get_ipython()
253 with TemporaryWorkingDirectory():
253 with TemporaryWorkingDirectory():
254 prefix = './foo'
254 prefix = './foo'
255 suffixes = ['1', '2']
255 suffixes = ['1', '2']
256 names = [prefix+s for s in suffixes]
256 names = [prefix+s for s in suffixes]
257 for n in names:
257 for n in names:
258 open(n, 'w').close()
258 open(n, 'w').close()
259
259
260 # Check simple completion
260 # Check simple completion
261 c = ip.complete(prefix)[1]
261 c = ip.complete(prefix)[1]
262 nt.assert_equal(c, names)
262 nt.assert_equal(c, names)
263
263
264 # Now check with a function call
264 # Now check with a function call
265 cmd = 'a = f("%s' % prefix
265 cmd = 'a = f("%s' % prefix
266 c = ip.complete(prefix, cmd)[1]
266 c = ip.complete(prefix, cmd)[1]
267 comp = [prefix+s for s in suffixes]
267 comp = [prefix+s for s in suffixes]
268 nt.assert_equal(c, comp)
268 nt.assert_equal(c, comp)
269
269
270
270
271 def test_greedy_completions():
271 def test_greedy_completions():
272 ip = get_ipython()
272 ip = get_ipython()
273 ip.ex('a=list(range(5))')
273 ip.ex('a=list(range(5))')
274 _,c = ip.complete('.',line='a[0].')
274 _,c = ip.complete('.',line='a[0].')
275 nt.assert_false('a[0].real' in c,
275 nt.assert_false('a[0].real' in c,
276 "Shouldn't have completed on a[0]: %s"%c)
276 "Shouldn't have completed on a[0]: %s"%c)
277 with greedy_completion():
277 with greedy_completion():
278 _,c = ip.complete('.',line='a[0].')
278 _,c = ip.complete('.',line='a[0].')
279 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)
280
280
281
281
282 def test_omit__names():
282 def test_omit__names():
283 # also happens to test IPCompleter as a configurable
283 # also happens to test IPCompleter as a configurable
284 ip = get_ipython()
284 ip = get_ipython()
285 ip._hidden_attr = 1
285 ip._hidden_attr = 1
286 ip._x = {}
286 ip._x = {}
287 c = ip.Completer
287 c = ip.Completer
288 ip.ex('ip=get_ipython()')
288 ip.ex('ip=get_ipython()')
289 cfg = Config()
289 cfg = Config()
290 cfg.IPCompleter.omit__names = 0
290 cfg.IPCompleter.omit__names = 0
291 c.update_config(cfg)
291 c.update_config(cfg)
292 s,matches = c.complete('ip.')
292 s,matches = c.complete('ip.')
293 nt.assert_in('ip.__str__', matches)
293 nt.assert_in('ip.__str__', matches)
294 nt.assert_in('ip._hidden_attr', matches)
294 nt.assert_in('ip._hidden_attr', matches)
295 cfg = Config()
295 cfg = Config()
296 cfg.IPCompleter.omit__names = 1
296 cfg.IPCompleter.omit__names = 1
297 c.update_config(cfg)
297 c.update_config(cfg)
298 s,matches = c.complete('ip.')
298 s,matches = c.complete('ip.')
299 nt.assert_not_in('ip.__str__', matches)
299 nt.assert_not_in('ip.__str__', matches)
300 nt.assert_in('ip._hidden_attr', matches)
300 nt.assert_in('ip._hidden_attr', matches)
301 cfg = Config()
301 cfg = Config()
302 cfg.IPCompleter.omit__names = 2
302 cfg.IPCompleter.omit__names = 2
303 c.update_config(cfg)
303 c.update_config(cfg)
304 s,matches = c.complete('ip.')
304 s,matches = c.complete('ip.')
305 nt.assert_not_in('ip.__str__', matches)
305 nt.assert_not_in('ip.__str__', matches)
306 nt.assert_not_in('ip._hidden_attr', matches)
306 nt.assert_not_in('ip._hidden_attr', matches)
307 s,matches = c.complete('ip._x.')
307 s,matches = c.complete('ip._x.')
308 nt.assert_in('ip._x.keys', matches)
308 nt.assert_in('ip._x.keys', matches)
309 del ip._hidden_attr
309 del ip._hidden_attr
310
310
311
311
312 def test_limit_to__all__False_ok():
312 def test_limit_to__all__False_ok():
313 ip = get_ipython()
313 ip = get_ipython()
314 c = ip.Completer
314 c = ip.Completer
315 ip.ex('class D: x=24')
315 ip.ex('class D: x=24')
316 ip.ex('d=D()')
316 ip.ex('d=D()')
317 cfg = Config()
317 cfg = Config()
318 cfg.IPCompleter.limit_to__all__ = False
318 cfg.IPCompleter.limit_to__all__ = False
319 c.update_config(cfg)
319 c.update_config(cfg)
320 s, matches = c.complete('d.')
320 s, matches = c.complete('d.')
321 nt.assert_in('d.x', matches)
321 nt.assert_in('d.x', matches)
322
322
323
323
324 def test_limit_to__all__True_ok():
324 def test_limit_to__all__True_ok():
325 ip = get_ipython()
325 ip = get_ipython()
326 c = ip.Completer
326 c = ip.Completer
327 ip.ex('class D: x=24')
327 ip.ex('class D: x=24')
328 ip.ex('d=D()')
328 ip.ex('d=D()')
329 ip.ex("d.__all__=['z']")
329 ip.ex("d.__all__=['z']")
330 cfg = Config()
330 cfg = Config()
331 cfg.IPCompleter.limit_to__all__ = True
331 cfg.IPCompleter.limit_to__all__ = True
332 c.update_config(cfg)
332 c.update_config(cfg)
333 s, matches = c.complete('d.')
333 s, matches = c.complete('d.')
334 nt.assert_in('d.z', matches)
334 nt.assert_in('d.z', matches)
335 nt.assert_not_in('d.x', matches)
335 nt.assert_not_in('d.x', matches)
336
336
337
337
338 def test_get__all__entries_ok():
338 def test_get__all__entries_ok():
339 class A(object):
339 class A(object):
340 __all__ = ['x', 1]
340 __all__ = ['x', 1]
341 words = completer.get__all__entries(A())
341 words = completer.get__all__entries(A())
342 nt.assert_equal(words, ['x'])
342 nt.assert_equal(words, ['x'])
343
343
344
344
345 def test_get__all__entries_no__all__ok():
345 def test_get__all__entries_no__all__ok():
346 class A(object):
346 class A(object):
347 pass
347 pass
348 words = completer.get__all__entries(A())
348 words = completer.get__all__entries(A())
349 nt.assert_equal(words, [])
349 nt.assert_equal(words, [])
350
350
351
351
352 def test_func_kw_completions():
352 def test_func_kw_completions():
353 ip = get_ipython()
353 ip = get_ipython()
354 c = ip.Completer
354 c = ip.Completer
355 ip.ex('def myfunc(a=1,b=2): return a+b')
355 ip.ex('def myfunc(a=1,b=2): return a+b')
356 s, matches = c.complete(None, 'myfunc(1,b')
356 s, matches = c.complete(None, 'myfunc(1,b')
357 nt.assert_in('b=', matches)
357 nt.assert_in('b=', matches)
358 # Simulate completing with cursor right after b (pos==10):
358 # Simulate completing with cursor right after b (pos==10):
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 nt.assert_in('b=', matches)
360 nt.assert_in('b=', matches)
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 nt.assert_in('b=', matches)
362 nt.assert_in('b=', matches)
363 #builtin function
363 #builtin function
364 s, matches = c.complete(None, 'min(k, k')
364 s, matches = c.complete(None, 'min(k, k')
365 nt.assert_in('key=', matches)
365 nt.assert_in('key=', matches)
366
366
367
367
368 def test_default_arguments_from_docstring():
368 def test_default_arguments_from_docstring():
369 doc = min.__doc__
369 doc = min.__doc__
370 ip = get_ipython()
370 ip = get_ipython()
371 c = ip.Completer
371 c = ip.Completer
372 kwd = c._default_arguments_from_docstring(
372 kwd = c._default_arguments_from_docstring(
373 'min(iterable[, key=func]) -> value')
373 'min(iterable[, key=func]) -> value')
374 nt.assert_equal(kwd, ['key'])
374 nt.assert_equal(kwd, ['key'])
375 #with cython type etc
375 #with cython type etc
376 kwd = c._default_arguments_from_docstring(
376 kwd = c._default_arguments_from_docstring(
377 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
377 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
378 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
378 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
379 #white spaces
379 #white spaces
380 kwd = c._default_arguments_from_docstring(
380 kwd = c._default_arguments_from_docstring(
381 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
381 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
382 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
382 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
383
383
384 def test_line_magics():
384 def test_line_magics():
385 ip = get_ipython()
385 ip = get_ipython()
386 c = ip.Completer
386 c = ip.Completer
387 s, matches = c.complete(None, 'lsmag')
387 s, matches = c.complete(None, 'lsmag')
388 nt.assert_in('%lsmagic', matches)
388 nt.assert_in('%lsmagic', matches)
389 s, matches = c.complete(None, '%lsmag')
389 s, matches = c.complete(None, '%lsmag')
390 nt.assert_in('%lsmagic', matches)
390 nt.assert_in('%lsmagic', matches)
391
391
392
392
393 def test_cell_magics():
393 def test_cell_magics():
394 from IPython.core.magic import register_cell_magic
394 from IPython.core.magic import register_cell_magic
395
395
396 @register_cell_magic
396 @register_cell_magic
397 def _foo_cellm(line, cell):
397 def _foo_cellm(line, cell):
398 pass
398 pass
399
399
400 ip = get_ipython()
400 ip = get_ipython()
401 c = ip.Completer
401 c = ip.Completer
402
402
403 s, matches = c.complete(None, '_foo_ce')
403 s, matches = c.complete(None, '_foo_ce')
404 nt.assert_in('%%_foo_cellm', matches)
404 nt.assert_in('%%_foo_cellm', matches)
405 s, matches = c.complete(None, '%%_foo_ce')
405 s, matches = c.complete(None, '%%_foo_ce')
406 nt.assert_in('%%_foo_cellm', matches)
406 nt.assert_in('%%_foo_cellm', matches)
407
407
408
408
409 def test_line_cell_magics():
409 def test_line_cell_magics():
410 from IPython.core.magic import register_line_cell_magic
410 from IPython.core.magic import register_line_cell_magic
411
411
412 @register_line_cell_magic
412 @register_line_cell_magic
413 def _bar_cellm(line, cell):
413 def _bar_cellm(line, cell):
414 pass
414 pass
415
415
416 ip = get_ipython()
416 ip = get_ipython()
417 c = ip.Completer
417 c = ip.Completer
418
418
419 # The policy here is trickier, see comments in completion code. The
419 # The policy here is trickier, see comments in completion code. The
420 # returned values depend on whether the user passes %% or not explicitly,
420 # returned values depend on whether the user passes %% or not explicitly,
421 # and this will show a difference if the same name is both a line and cell
421 # and this will show a difference if the same name is both a line and cell
422 # magic.
422 # magic.
423 s, matches = c.complete(None, '_bar_ce')
423 s, matches = c.complete(None, '_bar_ce')
424 nt.assert_in('%_bar_cellm', matches)
424 nt.assert_in('%_bar_cellm', matches)
425 nt.assert_in('%%_bar_cellm', matches)
425 nt.assert_in('%%_bar_cellm', matches)
426 s, matches = c.complete(None, '%_bar_ce')
426 s, matches = c.complete(None, '%_bar_ce')
427 nt.assert_in('%_bar_cellm', matches)
427 nt.assert_in('%_bar_cellm', matches)
428 nt.assert_in('%%_bar_cellm', matches)
428 nt.assert_in('%%_bar_cellm', matches)
429 s, matches = c.complete(None, '%%_bar_ce')
429 s, matches = c.complete(None, '%%_bar_ce')
430 nt.assert_not_in('%_bar_cellm', matches)
430 nt.assert_not_in('%_bar_cellm', matches)
431 nt.assert_in('%%_bar_cellm', matches)
431 nt.assert_in('%%_bar_cellm', matches)
432
432
433
433
434 def test_magic_completion_order():
434 def test_magic_completion_order():
435
435
436 ip = get_ipython()
436 ip = get_ipython()
437 c = ip.Completer
437 c = ip.Completer
438
438
439 # Test ordering of magics and non-magics with the same name
439 # Test ordering of magics and non-magics with the same name
440 # We want the non-magic first
440 # We want the non-magic first
441
441
442 # Before importing matplotlib, there should only be one option:
442 # Before importing matplotlib, there should only be one option:
443
443
444 text, matches = c.complete('mat')
444 text, matches = c.complete('mat')
445 nt.assert_equal(matches, ["%matplotlib"])
445 nt.assert_equal(matches, ["%matplotlib"])
446
446
447
447
448 ip.run_cell("matplotlib = 1") # introduce name into namespace
448 ip.run_cell("matplotlib = 1") # introduce name into namespace
449
449
450 # After the import, there should be two options, ordered like this:
450 # After the import, there should be two options, ordered like this:
451 text, matches = c.complete('mat')
451 text, matches = c.complete('mat')
452 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
452 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
453
453
454
454
455 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
455 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
456
456
457 # Order of user variable and line and cell magics with same name:
457 # Order of user variable and line and cell magics with same name:
458 text, matches = c.complete('timeit')
458 text, matches = c.complete('timeit')
459 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
459 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
460
460
461
461
462 def test_dict_key_completion_string():
462 def test_dict_key_completion_string():
463 """Test dictionary key completion for string keys"""
463 """Test dictionary key completion for string keys"""
464 ip = get_ipython()
464 ip = get_ipython()
465 complete = ip.Completer.complete
465 complete = ip.Completer.complete
466
466
467 ip.user_ns['d'] = {'abc': None}
467 ip.user_ns['d'] = {'abc': None}
468
468
469 # check completion at different stages
469 # check completion at different stages
470 _, matches = complete(line_buffer="d[")
470 _, matches = complete(line_buffer="d[")
471 nt.assert_in("'abc'", matches)
471 nt.assert_in("'abc'", matches)
472 nt.assert_not_in("'abc']", matches)
472 nt.assert_not_in("'abc']", matches)
473
473
474 _, matches = complete(line_buffer="d['")
474 _, matches = complete(line_buffer="d['")
475 nt.assert_in("abc", matches)
475 nt.assert_in("abc", matches)
476 nt.assert_not_in("abc']", matches)
476 nt.assert_not_in("abc']", matches)
477
477
478 _, matches = complete(line_buffer="d['a")
478 _, matches = complete(line_buffer="d['a")
479 nt.assert_in("abc", matches)
479 nt.assert_in("abc", matches)
480 nt.assert_not_in("abc']", matches)
480 nt.assert_not_in("abc']", matches)
481
481
482 # check use of different quoting
482 # check use of different quoting
483 _, matches = complete(line_buffer="d[\"")
483 _, matches = complete(line_buffer="d[\"")
484 nt.assert_in("abc", matches)
484 nt.assert_in("abc", matches)
485 nt.assert_not_in('abc\"]', matches)
485 nt.assert_not_in('abc\"]', matches)
486
486
487 _, matches = complete(line_buffer="d[\"a")
487 _, matches = complete(line_buffer="d[\"a")
488 nt.assert_in("abc", matches)
488 nt.assert_in("abc", matches)
489 nt.assert_not_in('abc\"]', matches)
489 nt.assert_not_in('abc\"]', matches)
490
490
491 # check sensitivity to following context
491 # check sensitivity to following context
492 _, matches = complete(line_buffer="d[]", cursor_pos=2)
492 _, matches = complete(line_buffer="d[]", cursor_pos=2)
493 nt.assert_in("'abc'", matches)
493 nt.assert_in("'abc'", matches)
494
494
495 _, matches = complete(line_buffer="d['']", cursor_pos=3)
495 _, matches = complete(line_buffer="d['']", cursor_pos=3)
496 nt.assert_in("abc", matches)
496 nt.assert_in("abc", matches)
497 nt.assert_not_in("abc'", matches)
497 nt.assert_not_in("abc'", matches)
498 nt.assert_not_in("abc']", matches)
498 nt.assert_not_in("abc']", matches)
499
499
500 # check multiple solutions are correctly returned and that noise is not
500 # check multiple solutions are correctly returned and that noise is not
501 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
501 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
502 5: None}
502 5: None}
503
503
504 _, matches = complete(line_buffer="d['a")
504 _, matches = complete(line_buffer="d['a")
505 nt.assert_in("abc", matches)
505 nt.assert_in("abc", matches)
506 nt.assert_in("abd", matches)
506 nt.assert_in("abd", matches)
507 nt.assert_not_in("bad", matches)
507 nt.assert_not_in("bad", matches)
508 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
508 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
509
509
510 # check escaping and whitespace
510 # check escaping and whitespace
511 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
511 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
512 _, matches = complete(line_buffer="d['a")
512 _, matches = complete(line_buffer="d['a")
513 nt.assert_in("a\\nb", matches)
513 nt.assert_in("a\\nb", matches)
514 nt.assert_in("a\\'b", matches)
514 nt.assert_in("a\\'b", matches)
515 nt.assert_in("a\"b", matches)
515 nt.assert_in("a\"b", matches)
516 nt.assert_in("a word", matches)
516 nt.assert_in("a word", matches)
517 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
517 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
518
518
519 # - can complete on non-initial word of the string
519 # - can complete on non-initial word of the string
520 _, matches = complete(line_buffer="d['a w")
520 _, matches = complete(line_buffer="d['a w")
521 nt.assert_in("word", matches)
521 nt.assert_in("word", matches)
522
522
523 # - understands quote escaping
523 # - understands quote escaping
524 _, matches = complete(line_buffer="d['a\\'")
524 _, matches = complete(line_buffer="d['a\\'")
525 nt.assert_in("b", matches)
525 nt.assert_in("b", matches)
526
526
527 # - default quoting should work like repr
527 # - default quoting should work like repr
528 _, matches = complete(line_buffer="d[")
528 _, matches = complete(line_buffer="d[")
529 nt.assert_in("\"a'b\"", matches)
529 nt.assert_in("\"a'b\"", matches)
530
530
531 # - when opening quote with ", possible to match with unescaped apostrophe
531 # - when opening quote with ", possible to match with unescaped apostrophe
532 _, matches = complete(line_buffer="d[\"a'")
532 _, matches = complete(line_buffer="d[\"a'")
533 nt.assert_in("b", matches)
533 nt.assert_in("b", matches)
534
534
535 # need to not split at delims that readline won't split at
535 # need to not split at delims that readline won't split at
536 if '-' not in ip.Completer.splitter.delims:
536 if '-' not in ip.Completer.splitter.delims:
537 ip.user_ns['d'] = {'before-after': None}
537 ip.user_ns['d'] = {'before-after': None}
538 _, matches = complete(line_buffer="d['before-af")
538 _, matches = complete(line_buffer="d['before-af")
539 nt.assert_in('before-after', matches)
539 nt.assert_in('before-after', matches)
540
540
541 def test_dict_key_completion_contexts():
541 def test_dict_key_completion_contexts():
542 """Test expression contexts in which dict key completion occurs"""
542 """Test expression contexts in which dict key completion occurs"""
543 ip = get_ipython()
543 ip = get_ipython()
544 complete = ip.Completer.complete
544 complete = ip.Completer.complete
545 d = {'abc': None}
545 d = {'abc': None}
546 ip.user_ns['d'] = d
546 ip.user_ns['d'] = d
547
547
548 class C:
548 class C:
549 data = d
549 data = d
550 ip.user_ns['C'] = C
550 ip.user_ns['C'] = C
551 ip.user_ns['get'] = lambda: d
551 ip.user_ns['get'] = lambda: d
552
552
553 def assert_no_completion(**kwargs):
553 def assert_no_completion(**kwargs):
554 _, matches = complete(**kwargs)
554 _, matches = complete(**kwargs)
555 nt.assert_not_in('abc', matches)
555 nt.assert_not_in('abc', matches)
556 nt.assert_not_in('abc\'', matches)
556 nt.assert_not_in('abc\'', matches)
557 nt.assert_not_in('abc\']', matches)
557 nt.assert_not_in('abc\']', matches)
558 nt.assert_not_in('\'abc\'', matches)
558 nt.assert_not_in('\'abc\'', matches)
559 nt.assert_not_in('\'abc\']', matches)
559 nt.assert_not_in('\'abc\']', matches)
560
560
561 def assert_completion(**kwargs):
561 def assert_completion(**kwargs):
562 _, matches = complete(**kwargs)
562 _, matches = complete(**kwargs)
563 nt.assert_in("'abc'", matches)
563 nt.assert_in("'abc'", matches)
564 nt.assert_not_in("'abc']", matches)
564 nt.assert_not_in("'abc']", matches)
565
565
566 # no completion after string closed, even if reopened
566 # no completion after string closed, even if reopened
567 assert_no_completion(line_buffer="d['a'")
567 assert_no_completion(line_buffer="d['a'")
568 assert_no_completion(line_buffer="d[\"a\"")
568 assert_no_completion(line_buffer="d[\"a\"")
569 assert_no_completion(line_buffer="d['a' + ")
569 assert_no_completion(line_buffer="d['a' + ")
570 assert_no_completion(line_buffer="d['a' + '")
570 assert_no_completion(line_buffer="d['a' + '")
571
571
572 # completion in non-trivial expressions
572 # completion in non-trivial expressions
573 assert_completion(line_buffer="+ d[")
573 assert_completion(line_buffer="+ d[")
574 assert_completion(line_buffer="(d[")
574 assert_completion(line_buffer="(d[")
575 assert_completion(line_buffer="C.data[")
575 assert_completion(line_buffer="C.data[")
576
576
577 # greedy flag
577 # greedy flag
578 def assert_completion(**kwargs):
578 def assert_completion(**kwargs):
579 _, matches = complete(**kwargs)
579 _, matches = complete(**kwargs)
580 nt.assert_in("get()['abc']", matches)
580 nt.assert_in("get()['abc']", matches)
581
581
582 assert_no_completion(line_buffer="get()[")
582 assert_no_completion(line_buffer="get()[")
583 with greedy_completion():
583 with greedy_completion():
584 assert_completion(line_buffer="get()[")
584 assert_completion(line_buffer="get()[")
585 assert_completion(line_buffer="get()['")
585 assert_completion(line_buffer="get()['")
586 assert_completion(line_buffer="get()['a")
586 assert_completion(line_buffer="get()['a")
587 assert_completion(line_buffer="get()['ab")
587 assert_completion(line_buffer="get()['ab")
588 assert_completion(line_buffer="get()['abc")
588 assert_completion(line_buffer="get()['abc")
589
589
590
590
591
591
592 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
592 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
593 def test_dict_key_completion_bytes():
593 def test_dict_key_completion_bytes():
594 """Test handling of bytes in dict key completion"""
594 """Test handling of bytes in dict key completion"""
595 ip = get_ipython()
595 ip = get_ipython()
596 complete = ip.Completer.complete
596 complete = ip.Completer.complete
597
597
598 ip.user_ns['d'] = {'abc': None, b'abd': None}
598 ip.user_ns['d'] = {'abc': None, b'abd': None}
599
599
600 _, matches = complete(line_buffer="d[")
600 _, matches = complete(line_buffer="d[")
601 nt.assert_in("'abc'", matches)
601 nt.assert_in("'abc'", matches)
602 nt.assert_in("b'abd'", matches)
602 nt.assert_in("b'abd'", matches)
603
603
604 if False: # not currently implemented
604 if False: # not currently implemented
605 _, matches = complete(line_buffer="d[b")
605 _, matches = complete(line_buffer="d[b")
606 nt.assert_in("b'abd'", matches)
606 nt.assert_in("b'abd'", matches)
607 nt.assert_not_in("b'abc'", matches)
607 nt.assert_not_in("b'abc'", matches)
608
608
609 _, matches = complete(line_buffer="d[b'")
609 _, matches = complete(line_buffer="d[b'")
610 nt.assert_in("abd", matches)
610 nt.assert_in("abd", matches)
611 nt.assert_not_in("abc", matches)
611 nt.assert_not_in("abc", matches)
612
612
613 _, matches = complete(line_buffer="d[B'")
613 _, matches = complete(line_buffer="d[B'")
614 nt.assert_in("abd", matches)
614 nt.assert_in("abd", matches)
615 nt.assert_not_in("abc", matches)
615 nt.assert_not_in("abc", matches)
616
616
617 _, matches = complete(line_buffer="d['")
617 _, matches = complete(line_buffer="d['")
618 nt.assert_in("abc", matches)
618 nt.assert_in("abc", matches)
619 nt.assert_not_in("abd", matches)
619 nt.assert_not_in("abd", matches)
620
620
621
621
622 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
622 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
623 def test_dict_key_completion_unicode_py2():
623 def test_dict_key_completion_unicode_py2():
624 """Test handling of unicode in dict key completion"""
624 """Test handling of unicode in dict key completion"""
625 ip = get_ipython()
625 ip = get_ipython()
626 complete = ip.Completer.complete
626 complete = ip.Completer.complete
627
627
628 ip.user_ns['d'] = {u'abc': None,
628 ip.user_ns['d'] = {u'abc': None,
629 u'a\u05d0b': None}
629 u'a\u05d0b': None}
630
630
631 _, matches = complete(line_buffer="d[")
631 _, matches = complete(line_buffer="d[")
632 nt.assert_in("u'abc'", matches)
632 nt.assert_in("u'abc'", matches)
633 nt.assert_in("u'a\\u05d0b'", matches)
633 nt.assert_in("u'a\\u05d0b'", matches)
634
634
635 _, matches = complete(line_buffer="d['a")
635 _, matches = complete(line_buffer="d['a")
636 nt.assert_in("abc", matches)
636 nt.assert_in("abc", matches)
637 nt.assert_not_in("a\\u05d0b", matches)
637 nt.assert_not_in("a\\u05d0b", matches)
638
638
639 _, matches = complete(line_buffer="d[u'a")
639 _, matches = complete(line_buffer="d[u'a")
640 nt.assert_in("abc", matches)
640 nt.assert_in("abc", matches)
641 nt.assert_in("a\\u05d0b", matches)
641 nt.assert_in("a\\u05d0b", matches)
642
642
643 _, matches = complete(line_buffer="d[U'a")
643 _, matches = complete(line_buffer="d[U'a")
644 nt.assert_in("abc", matches)
644 nt.assert_in("abc", matches)
645 nt.assert_in("a\\u05d0b", matches)
645 nt.assert_in("a\\u05d0b", matches)
646
646
647 # query using escape
647 # query using escape
648 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
648 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
649 nt.assert_in("u05d0b", matches) # tokenized after \\
649 nt.assert_in("u05d0b", matches) # tokenized after \\
650
650
651 # query using character
651 # query using character
652 _, matches = complete(line_buffer=u"d[u'a\u05d0")
652 _, matches = complete(line_buffer=u"d[u'a\u05d0")
653 nt.assert_in(u"a\u05d0b", matches)
653 nt.assert_in(u"a\u05d0b", matches)
654
654
655 with greedy_completion():
655 with greedy_completion():
656 _, matches = complete(line_buffer="d[")
656 _, matches = complete(line_buffer="d[")
657 nt.assert_in("d[u'abc']", matches)
657 nt.assert_in("d[u'abc']", matches)
658 nt.assert_in("d[u'a\\u05d0b']", matches)
658 nt.assert_in("d[u'a\\u05d0b']", matches)
659
659
660 _, matches = complete(line_buffer="d['a")
660 _, matches = complete(line_buffer="d['a")
661 nt.assert_in("d['abc']", matches)
661 nt.assert_in("d['abc']", matches)
662 nt.assert_not_in("d[u'a\\u05d0b']", matches)
662 nt.assert_not_in("d[u'a\\u05d0b']", matches)
663
663
664 _, matches = complete(line_buffer="d[u'a")
664 _, matches = complete(line_buffer="d[u'a")
665 nt.assert_in("d[u'abc']", matches)
665 nt.assert_in("d[u'abc']", matches)
666 nt.assert_in("d[u'a\\u05d0b']", matches)
666 nt.assert_in("d[u'a\\u05d0b']", matches)
667
667
668 _, matches = complete(line_buffer="d[U'a")
668 _, matches = complete(line_buffer="d[U'a")
669 nt.assert_in("d[U'abc']", matches)
669 nt.assert_in("d[U'abc']", matches)
670 nt.assert_in("d[U'a\\u05d0b']", matches)
670 nt.assert_in("d[U'a\\u05d0b']", matches)
671
671
672 # query using escape
672 # query using escape
673 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
673 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
674 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
674 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
675
675
676 # query using character
676 # query using character
677 _, matches = complete(line_buffer=u"d[u'a\u05d0")
677 _, matches = complete(line_buffer=u"d[u'a\u05d0")
678 nt.assert_in(u"d[u'a\u05d0b']", matches)
678 nt.assert_in(u"d[u'a\u05d0b']", matches)
679
679
680
680
681 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
681 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
682 def test_dict_key_completion_unicode_py3():
682 def test_dict_key_completion_unicode_py3():
683 """Test handling of unicode in dict key completion"""
683 """Test handling of unicode in dict key completion"""
684 ip = get_ipython()
684 ip = get_ipython()
685 complete = ip.Completer.complete
685 complete = ip.Completer.complete
686
686
687 ip.user_ns['d'] = {u'a\u05d0': None}
687 ip.user_ns['d'] = {u'a\u05d0': None}
688
688
689 # query using escape
689 # query using escape
690 _, matches = complete(line_buffer="d['a\\u05d0")
690 _, matches = complete(line_buffer="d['a\\u05d0")
691 nt.assert_in("u05d0", matches) # tokenized after \\
691 nt.assert_in("u05d0", matches) # tokenized after \\
692
692
693 # query using character
693 # query using character
694 _, matches = complete(line_buffer="d['a\u05d0")
694 _, matches = complete(line_buffer="d['a\u05d0")
695 nt.assert_in(u"a\u05d0", matches)
695 nt.assert_in(u"a\u05d0", matches)
696
696
697 with greedy_completion():
697 with greedy_completion():
698 # query using escape
698 # query using escape
699 _, matches = complete(line_buffer="d['a\\u05d0")
699 _, matches = complete(line_buffer="d['a\\u05d0")
700 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
700 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
701
701
702 # query using character
702 # query using character
703 _, matches = complete(line_buffer="d['a\u05d0")
703 _, matches = complete(line_buffer="d['a\u05d0")
704 nt.assert_in(u"d['a\u05d0']", matches)
704 nt.assert_in(u"d['a\u05d0']", matches)
705
705
706
706
707
707
708 @dec.skip_without('numpy')
708 @dec.skip_without('numpy')
709 def test_struct_array_key_completion():
709 def test_struct_array_key_completion():
710 """Test dict key completion applies to numpy struct arrays"""
710 """Test dict key completion applies to numpy struct arrays"""
711 import numpy
711 import numpy
712 ip = get_ipython()
712 ip = get_ipython()
713 complete = ip.Completer.complete
713 complete = ip.Completer.complete
714 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
714 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
715 _, matches = complete(line_buffer="d['")
715 _, matches = complete(line_buffer="d['")
716 nt.assert_in("hello", matches)
716 nt.assert_in("hello", matches)
717 nt.assert_in("world", matches)
717 nt.assert_in("world", matches)
718 # complete on the numpy struct itself
718 # complete on the numpy struct itself
719 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
719 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
720 ('my_data', '>f4', 5)])
720 ('my_data', '>f4', 5)])
721 x = numpy.zeros(2, dtype=dt)
721 x = numpy.zeros(2, dtype=dt)
722 ip.user_ns['d'] = x[1]
722 ip.user_ns['d'] = x[1]
723 _, matches = complete(line_buffer="d['")
723 _, matches = complete(line_buffer="d['")
724 nt.assert_in("my_head", matches)
724 nt.assert_in("my_head", matches)
725 nt.assert_in("my_data", matches)
725 nt.assert_in("my_data", matches)
726 # complete on a nested level
726 # complete on a nested level
727 with greedy_completion():
727 with greedy_completion():
728 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
728 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
729 _, matches = complete(line_buffer="d[1]['my_head']['")
729 _, matches = complete(line_buffer="d[1]['my_head']['")
730 nt.assert_true(any(["my_dt" in m for m in matches]))
730 nt.assert_true(any(["my_dt" in m for m in matches]))
731 nt.assert_true(any(["my_df" in m for m in matches]))
731 nt.assert_true(any(["my_df" in m for m in matches]))
732
732
733
733
734 @dec.skip_without('pandas')
734 @dec.skip_without('pandas')
735 def test_dataframe_key_completion():
735 def test_dataframe_key_completion():
736 """Test dict key completion applies to pandas DataFrames"""
736 """Test dict key completion applies to pandas DataFrames"""
737 import pandas
737 import pandas
738 ip = get_ipython()
738 ip = get_ipython()
739 complete = ip.Completer.complete
739 complete = ip.Completer.complete
740 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
740 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
741 _, matches = complete(line_buffer="d['")
741 _, matches = complete(line_buffer="d['")
742 nt.assert_in("hello", matches)
742 nt.assert_in("hello", matches)
743 nt.assert_in("world", matches)
743 nt.assert_in("world", matches)
744
744
745
745
746 def test_dict_key_completion_invalids():
746 def test_dict_key_completion_invalids():
747 """Smoke test cases dict key completion can't handle"""
747 """Smoke test cases dict key completion can't handle"""
748 ip = get_ipython()
748 ip = get_ipython()
749 complete = ip.Completer.complete
749 complete = ip.Completer.complete
750
750
751 ip.user_ns['no_getitem'] = None
751 ip.user_ns['no_getitem'] = None
752 ip.user_ns['no_keys'] = []
752 ip.user_ns['no_keys'] = []
753 ip.user_ns['cant_call_keys'] = dict
753 ip.user_ns['cant_call_keys'] = dict
754 ip.user_ns['empty'] = {}
754 ip.user_ns['empty'] = {}
755 ip.user_ns['d'] = {'abc': 5}
755 ip.user_ns['d'] = {'abc': 5}
756
756
757 _, matches = complete(line_buffer="no_getitem['")
757 _, matches = complete(line_buffer="no_getitem['")
758 _, matches = complete(line_buffer="no_keys['")
758 _, matches = complete(line_buffer="no_keys['")
759 _, matches = complete(line_buffer="cant_call_keys['")
759 _, matches = complete(line_buffer="cant_call_keys['")
760 _, matches = complete(line_buffer="empty['")
760 _, matches = complete(line_buffer="empty['")
761 _, matches = complete(line_buffer="name_error['")
761 _, matches = complete(line_buffer="name_error['")
762 _, matches = complete(line_buffer="d['\\") # incomplete escape
762 _, matches = complete(line_buffer="d['\\") # incomplete escape
763
763
764 class KeyCompletable(object):
764 class KeyCompletable(object):
765 def __init__(self, things=()):
765 def __init__(self, things=()):
766 self.things = things
766 self.things = things
767
767
768 def _ipython_key_completions_(self):
768 def _ipython_key_completions_(self):
769 return list(self.things)
769 return list(self.things)
770
770
771 def test_object_key_completion():
771 def test_object_key_completion():
772 ip = get_ipython()
772 ip = get_ipython()
773 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
773 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
774
774
775 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
775 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
776 nt.assert_in('qwerty', matches)
776 nt.assert_in('qwerty', matches)
777 nt.assert_in('qwick', matches)
777 nt.assert_in('qwick', matches)
778
778
779
779
780 def test_aimport_module_completer():
780 def test_aimport_module_completer():
781 ip = get_ipython()
781 ip = get_ipython()
782 _, matches = ip.complete('i', '%aimport i')
782 _, matches = ip.complete('i', '%aimport i')
783 nt.assert_in('io', matches)
783 nt.assert_in('io', matches)
784 nt.assert_not_in('int', matches)
784 nt.assert_not_in('int', matches)
785
785
786 def test_nested_import_module_completer():
787 ip = get_ipython()
788 _, matches = ip.complete(None, 'import IPython.co', 17)
789 nt.assert_in('IPython.core', matches)
790 nt.assert_not_in('import IPython.core', matches)
791 nt.assert_not_in('IPython.display', matches)
792
786 def test_import_module_completer():
793 def test_import_module_completer():
787 ip = get_ipython()
794 ip = get_ipython()
788 _, matches = ip.complete('i', 'import i')
795 _, matches = ip.complete('i', 'import i')
789 nt.assert_in('io', matches)
796 nt.assert_in('io', matches)
790 nt.assert_not_in('int', matches)
797 nt.assert_not_in('int', matches)
791
798
792 def test_from_module_completer():
799 def test_from_module_completer():
793 ip = get_ipython()
800 ip = get_ipython()
794 _, matches = ip.complete('B', 'from io import B')
801 _, matches = ip.complete('B', 'from io import B')
795 nt.assert_in('BytesIO', matches)
802 nt.assert_in('BytesIO', matches)
796 nt.assert_not_in('BaseException', matches)
803 nt.assert_not_in('BaseException', matches)
General Comments 0
You need to be logged in to leave comments. Login now