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