##// END OF EJS Templates
Prepare some test for pytest in completers....
Matthias Bussonnier -
Show More
@@ -1,1050 +1,1051 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 textwrap
9 import textwrap
10 import unittest
10 import unittest
11
11
12 from contextlib import contextmanager
12 from contextlib import contextmanager
13
13
14 import nose.tools as nt
14 import nose.tools as nt
15
15
16 from traitlets.config.loader import Config
16 from traitlets.config.loader import Config
17 from IPython import get_ipython
17 from IPython import get_ipython
18 from IPython.core import completer
18 from IPython.core import completer
19 from IPython.external import decorators
19 from IPython.external import decorators
20 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
21 from IPython.utils.generics import complete_object
21 from IPython.utils.generics import complete_object
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24 from IPython.core.completer import (
24 from IPython.core.completer import (
25 Completion, provisionalcompleter, match_dict_keys, _deduplicate_completions)
25 Completion, provisionalcompleter, match_dict_keys, _deduplicate_completions)
26 from nose.tools import assert_in, assert_not_in
26 from nose.tools import assert_in, assert_not_in
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Test functions
29 # Test functions
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 @contextmanager
32 @contextmanager
33 def greedy_completion():
33 def greedy_completion():
34 ip = get_ipython()
34 ip = get_ipython()
35 greedy_original = ip.Completer.greedy
35 greedy_original = ip.Completer.greedy
36 try:
36 try:
37 ip.Completer.greedy = True
37 ip.Completer.greedy = True
38 yield
38 yield
39 finally:
39 finally:
40 ip.Completer.greedy = greedy_original
40 ip.Completer.greedy = greedy_original
41
41
42 def test_protect_filename():
42 def test_protect_filename():
43 if sys.platform == 'win32':
43 if sys.platform == 'win32':
44 pairs = [('abc','abc'),
44 pairs = [('abc','abc'),
45 (' abc','" abc"'),
45 (' abc','" abc"'),
46 ('a bc','"a bc"'),
46 ('a bc','"a bc"'),
47 ('a bc','"a bc"'),
47 ('a bc','"a bc"'),
48 (' bc','" bc"'),
48 (' bc','" bc"'),
49 ]
49 ]
50 else:
50 else:
51 pairs = [('abc','abc'),
51 pairs = [('abc','abc'),
52 (' abc',r'\ abc'),
52 (' abc',r'\ abc'),
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 (' bc',r'\ \ bc'),
55 (' bc',r'\ \ bc'),
56 # On posix, we also protect parens and other special characters.
56 # On posix, we also protect parens and other special characters.
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[1]bc', r'a\[1\]bc'),
60 ('a[1]bc', r'a\[1\]bc'),
61 ('a{1}bc', r'a\{1\}bc'),
61 ('a{1}bc', r'a\{1\}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 ('a^bc', r'a\^bc'),
72 ('a^bc', r'a\^bc'),
73 ('a&bc', r'a\&bc'),
73 ('a&bc', r'a\&bc'),
74 ]
74 ]
75 # run the actual tests
75 # run the actual tests
76 for s1, s2 in pairs:
76 for s1, s2 in pairs:
77 s1p = completer.protect_filename(s1)
77 s1p = completer.protect_filename(s1)
78 nt.assert_equal(s1p, s2)
78 nt.assert_equal(s1p, s2)
79
79
80
80
81 def check_line_split(splitter, test_specs):
81 def check_line_split(splitter, test_specs):
82 for part1, part2, split in test_specs:
82 for part1, part2, split in test_specs:
83 cursor_pos = len(part1)
83 cursor_pos = len(part1)
84 line = part1+part2
84 line = part1+part2
85 out = splitter.split_line(line, cursor_pos)
85 out = splitter.split_line(line, cursor_pos)
86 nt.assert_equal(out, split)
86 nt.assert_equal(out, split)
87
87
88
88
89 def test_line_split():
89 def test_line_split():
90 """Basic line splitter test with default specs."""
90 """Basic line splitter test with default specs."""
91 sp = completer.CompletionSplitter()
91 sp = completer.CompletionSplitter()
92 # The format of the test specs is: part1, part2, expected answer. Parts 1
92 # The format of the test specs is: part1, part2, expected answer. Parts 1
93 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
93 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
94 # was at the end of part1. So an empty part2 represents someone hitting
94 # was at the end of part1. So an empty part2 represents someone hitting
95 # tab at the end of the line, the most common case.
95 # tab at the end of the line, the most common case.
96 t = [('run some/scrip', '', 'some/scrip'),
96 t = [('run some/scrip', '', 'some/scrip'),
97 ('run scripts/er', 'ror.py foo', 'scripts/er'),
97 ('run scripts/er', 'ror.py foo', 'scripts/er'),
98 ('echo $HOM', '', 'HOM'),
98 ('echo $HOM', '', 'HOM'),
99 ('print sys.pa', '', 'sys.pa'),
99 ('print sys.pa', '', 'sys.pa'),
100 ('print(sys.pa', '', 'sys.pa'),
100 ('print(sys.pa', '', 'sys.pa'),
101 ("execfile('scripts/er", '', 'scripts/er'),
101 ("execfile('scripts/er", '', 'scripts/er'),
102 ('a[x.', '', 'x.'),
102 ('a[x.', '', 'x.'),
103 ('a[x.', 'y', 'x.'),
103 ('a[x.', 'y', 'x.'),
104 ('cd "some_file/', '', 'some_file/'),
104 ('cd "some_file/', '', 'some_file/'),
105 ]
105 ]
106 check_line_split(sp, t)
106 check_line_split(sp, t)
107 # Ensure splitting works OK with unicode by re-running the tests with
107 # Ensure splitting works OK with unicode by re-running the tests with
108 # all inputs turned into unicode
108 # all inputs turned into unicode
109 check_line_split(sp, [ map(str, p) for p in t] )
109 check_line_split(sp, [ map(str, p) for p in t] )
110
110
111
111
112 def test_custom_completion_error():
112 def test_custom_completion_error():
113 """Test that errors from custom attribute completers are silenced."""
113 """Test that errors from custom attribute completers are silenced."""
114 ip = get_ipython()
114 ip = get_ipython()
115 class A(object): pass
115 class A(object): pass
116 ip.user_ns['a'] = A()
116 ip.user_ns['a'] = A()
117
117
118 @complete_object.register(A)
118 @complete_object.register(A)
119 def complete_A(a, existing_completions):
119 def complete_A(a, existing_completions):
120 raise TypeError("this should be silenced")
120 raise TypeError("this should be silenced")
121
121
122 ip.complete("a.")
122 ip.complete("a.")
123
123
124
124
125 def test_unicode_completions():
125 def test_unicode_completions():
126 ip = get_ipython()
126 ip = get_ipython()
127 # Some strings that trigger different types of completion. Check them both
127 # Some strings that trigger different types of completion. Check them both
128 # in str and unicode forms
128 # in str and unicode forms
129 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
129 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
130 for t in s + list(map(str, s)):
130 for t in s + list(map(str, s)):
131 # We don't need to check exact completion values (they may change
131 # We don't need to check exact completion values (they may change
132 # depending on the state of the namespace, but at least no exceptions
132 # depending on the state of the namespace, but at least no exceptions
133 # should be thrown and the return value should be a pair of text, list
133 # should be thrown and the return value should be a pair of text, list
134 # values.
134 # values.
135 text, matches = ip.complete(t)
135 text, matches = ip.complete(t)
136 nt.assert_true(isinstance(text, str))
136 nt.assert_true(isinstance(text, str))
137 nt.assert_true(isinstance(matches, list))
137 nt.assert_true(isinstance(matches, list))
138
138
139 def test_latex_completions():
139 def test_latex_completions():
140 from IPython.core.latex_symbols import latex_symbols
140 from IPython.core.latex_symbols import latex_symbols
141 import random
141 import random
142 ip = get_ipython()
142 ip = get_ipython()
143 # Test some random unicode symbols
143 # Test some random unicode symbols
144 keys = random.sample(latex_symbols.keys(), 10)
144 keys = random.sample(latex_symbols.keys(), 10)
145 for k in keys:
145 for k in keys:
146 text, matches = ip.complete(k)
146 text, matches = ip.complete(k)
147 nt.assert_equal(len(matches),1)
147 nt.assert_equal(len(matches),1)
148 nt.assert_equal(text, k)
148 nt.assert_equal(text, k)
149 nt.assert_equal(matches[0], latex_symbols[k])
149 nt.assert_equal(matches[0], latex_symbols[k])
150 # Test a more complex line
150 # Test a more complex line
151 text, matches = ip.complete(u'print(\\alpha')
151 text, matches = ip.complete(u'print(\\alpha')
152 nt.assert_equal(text, u'\\alpha')
152 nt.assert_equal(text, u'\\alpha')
153 nt.assert_equal(matches[0], latex_symbols['\\alpha'])
153 nt.assert_equal(matches[0], latex_symbols['\\alpha'])
154 # Test multiple matching latex symbols
154 # Test multiple matching latex symbols
155 text, matches = ip.complete(u'\\al')
155 text, matches = ip.complete(u'\\al')
156 nt.assert_in('\\alpha', matches)
156 nt.assert_in('\\alpha', matches)
157 nt.assert_in('\\aleph', matches)
157 nt.assert_in('\\aleph', matches)
158
158
159
159
160
160
161
161
162 def test_back_latex_completion():
162 def test_back_latex_completion():
163 ip = get_ipython()
163 ip = get_ipython()
164
164
165 # do not return more than 1 matches fro \beta, only the latex one.
165 # do not return more than 1 matches fro \beta, only the latex one.
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], '\\beta')
168 nt.assert_equal(matches[0], '\\beta')
169
169
170 def test_back_unicode_completion():
170 def test_back_unicode_completion():
171 ip = get_ipython()
171 ip = get_ipython()
172
172
173 name, matches = ip.complete('\\β…€')
173 name, matches = ip.complete('\\β…€')
174 nt.assert_equal(len(matches), 1)
174 nt.assert_equal(len(matches), 1)
175 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
175 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
176
176
177
177
178 def test_forward_unicode_completion():
178 def test_forward_unicode_completion():
179 ip = get_ipython()
179 ip = get_ipython()
180
180
181 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
181 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
182 nt.assert_equal(len(matches), 1)
182 nt.assert_equal(len(matches), 1)
183 nt.assert_equal(matches[0], 'β…€')
183 nt.assert_equal(matches[0], 'β…€')
184
184
185 @nt.nottest # now we have a completion for \jmath
185 @nt.nottest # now we have a completion for \jmath
186 @decorators.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
186 @decorators.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
187 def test_no_ascii_back_completion():
187 def test_no_ascii_back_completion():
188 ip = get_ipython()
188 ip = get_ipython()
189 with TemporaryWorkingDirectory(): # Avoid any filename completions
189 with TemporaryWorkingDirectory(): # Avoid any filename completions
190 # single ascii letter that don't have yet completions
190 # single ascii letter that don't have yet completions
191 for letter in 'jJ' :
191 for letter in 'jJ' :
192 name, matches = ip.complete('\\'+letter)
192 name, matches = ip.complete('\\'+letter)
193 nt.assert_equal(matches, [])
193 nt.assert_equal(matches, [])
194
194
195
195
196
196
197
197
198 class CompletionSplitterTestCase(unittest.TestCase):
198 class CompletionSplitterTestCase(unittest.TestCase):
199 def setUp(self):
199 def setUp(self):
200 self.sp = completer.CompletionSplitter()
200 self.sp = completer.CompletionSplitter()
201
201
202 def test_delim_setting(self):
202 def test_delim_setting(self):
203 self.sp.delims = ' '
203 self.sp.delims = ' '
204 nt.assert_equal(self.sp.delims, ' ')
204 nt.assert_equal(self.sp.delims, ' ')
205 nt.assert_equal(self.sp._delim_expr, r'[\ ]')
205 nt.assert_equal(self.sp._delim_expr, r'[\ ]')
206
206
207 def test_spaces(self):
207 def test_spaces(self):
208 """Test with only spaces as split chars."""
208 """Test with only spaces as split chars."""
209 self.sp.delims = ' '
209 self.sp.delims = ' '
210 t = [('foo', '', 'foo'),
210 t = [('foo', '', 'foo'),
211 ('run foo', '', 'foo'),
211 ('run foo', '', 'foo'),
212 ('run foo', 'bar', 'foo'),
212 ('run foo', 'bar', 'foo'),
213 ]
213 ]
214 check_line_split(self.sp, t)
214 check_line_split(self.sp, t)
215
215
216
216
217 def test_has_open_quotes1():
217 def test_has_open_quotes1():
218 for s in ["'", "'''", "'hi' '"]:
218 for s in ["'", "'''", "'hi' '"]:
219 nt.assert_equal(completer.has_open_quotes(s), "'")
219 nt.assert_equal(completer.has_open_quotes(s), "'")
220
220
221
221
222 def test_has_open_quotes2():
222 def test_has_open_quotes2():
223 for s in ['"', '"""', '"hi" "']:
223 for s in ['"', '"""', '"hi" "']:
224 nt.assert_equal(completer.has_open_quotes(s), '"')
224 nt.assert_equal(completer.has_open_quotes(s), '"')
225
225
226
226
227 def test_has_open_quotes3():
227 def test_has_open_quotes3():
228 for s in ["''", "''' '''", "'hi' 'ipython'"]:
228 for s in ["''", "''' '''", "'hi' 'ipython'"]:
229 nt.assert_false(completer.has_open_quotes(s))
229 nt.assert_false(completer.has_open_quotes(s))
230
230
231
231
232 def test_has_open_quotes4():
232 def test_has_open_quotes4():
233 for s in ['""', '""" """', '"hi" "ipython"']:
233 for s in ['""', '""" """', '"hi" "ipython"']:
234 nt.assert_false(completer.has_open_quotes(s))
234 nt.assert_false(completer.has_open_quotes(s))
235
235
236
236
237 @decorators.knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
237 @decorators.knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
238 def test_abspath_file_completions():
238 def test_abspath_file_completions():
239 ip = get_ipython()
239 ip = get_ipython()
240 with TemporaryDirectory() as tmpdir:
240 with TemporaryDirectory() as tmpdir:
241 prefix = os.path.join(tmpdir, 'foo')
241 prefix = os.path.join(tmpdir, 'foo')
242 suffixes = ['1', '2']
242 suffixes = ['1', '2']
243 names = [prefix+s for s in suffixes]
243 names = [prefix+s for s in suffixes]
244 for n in names:
244 for n in names:
245 open(n, 'w').close()
245 open(n, 'w').close()
246
246
247 # Check simple completion
247 # Check simple completion
248 c = ip.complete(prefix)[1]
248 c = ip.complete(prefix)[1]
249 nt.assert_equal(c, names)
249 nt.assert_equal(c, names)
250
250
251 # Now check with a function call
251 # Now check with a function call
252 cmd = 'a = f("%s' % prefix
252 cmd = 'a = f("%s' % prefix
253 c = ip.complete(prefix, cmd)[1]
253 c = ip.complete(prefix, cmd)[1]
254 comp = [prefix+s for s in suffixes]
254 comp = [prefix+s for s in suffixes]
255 nt.assert_equal(c, comp)
255 nt.assert_equal(c, comp)
256
256
257
257
258 def test_local_file_completions():
258 def test_local_file_completions():
259 ip = get_ipython()
259 ip = get_ipython()
260 with TemporaryWorkingDirectory():
260 with TemporaryWorkingDirectory():
261 prefix = './foo'
261 prefix = './foo'
262 suffixes = ['1', '2']
262 suffixes = ['1', '2']
263 names = [prefix+s for s in suffixes]
263 names = [prefix+s for s in suffixes]
264 for n in names:
264 for n in names:
265 open(n, 'w').close()
265 open(n, 'w').close()
266
266
267 # Check simple completion
267 # Check simple completion
268 c = ip.complete(prefix)[1]
268 c = ip.complete(prefix)[1]
269 nt.assert_equal(c, names)
269 nt.assert_equal(c, names)
270
270
271 # Now check with a function call
271 # Now check with a function call
272 cmd = 'a = f("%s' % prefix
272 cmd = 'a = f("%s' % prefix
273 c = ip.complete(prefix, cmd)[1]
273 c = ip.complete(prefix, cmd)[1]
274 comp = set(prefix+s for s in suffixes)
274 comp = set(prefix+s for s in suffixes)
275 nt.assert_true(comp.issubset(set(c)))
275 nt.assert_true(comp.issubset(set(c)))
276
276
277
277
278 def test_quoted_file_completions():
278 def test_quoted_file_completions():
279 ip = get_ipython()
279 ip = get_ipython()
280 with TemporaryWorkingDirectory():
280 with TemporaryWorkingDirectory():
281 name = "foo'bar"
281 name = "foo'bar"
282 open(name, 'w').close()
282 open(name, 'w').close()
283
283
284 # Don't escape Windows
284 # Don't escape Windows
285 escaped = name if sys.platform == "win32" else "foo\\'bar"
285 escaped = name if sys.platform == "win32" else "foo\\'bar"
286
286
287 # Single quote matches embedded single quote
287 # Single quote matches embedded single quote
288 text = "open('foo"
288 text = "open('foo"
289 c = ip.Completer._complete(cursor_line=0,
289 c = ip.Completer._complete(cursor_line=0,
290 cursor_pos=len(text),
290 cursor_pos=len(text),
291 full_text=text)[1]
291 full_text=text)[1]
292 nt.assert_equal(c, [escaped])
292 nt.assert_equal(c, [escaped])
293
293
294 # Double quote requires no escape
294 # Double quote requires no escape
295 text = 'open("foo'
295 text = 'open("foo'
296 c = ip.Completer._complete(cursor_line=0,
296 c = ip.Completer._complete(cursor_line=0,
297 cursor_pos=len(text),
297 cursor_pos=len(text),
298 full_text=text)[1]
298 full_text=text)[1]
299 nt.assert_equal(c, [name])
299 nt.assert_equal(c, [name])
300
300
301 # No quote requires an escape
301 # No quote requires an escape
302 text = '%ls foo'
302 text = '%ls foo'
303 c = ip.Completer._complete(cursor_line=0,
303 c = ip.Completer._complete(cursor_line=0,
304 cursor_pos=len(text),
304 cursor_pos=len(text),
305 full_text=text)[1]
305 full_text=text)[1]
306 nt.assert_equal(c, [escaped])
306 nt.assert_equal(c, [escaped])
307
307
308
308
309 def test_jedi():
309 def test_jedi():
310 """
310 """
311 A couple of issue we had with Jedi
311 A couple of issue we had with Jedi
312 """
312 """
313 ip = get_ipython()
313 ip = get_ipython()
314
314
315 def _test_complete(reason, s, comp, start=None, end=None):
315 def _test_complete(reason, s, comp, start=None, end=None):
316 l = len(s)
316 l = len(s)
317 start = start if start is not None else l
317 start = start if start is not None else l
318 end = end if end is not None else l
318 end = end if end is not None else l
319 with provisionalcompleter():
319 with provisionalcompleter():
320 ip.Completer.use_jedi = True
320 ip.Completer.use_jedi = True
321 completions = set(ip.Completer.completions(s, l))
321 completions = set(ip.Completer.completions(s, l))
322 ip.Completer.use_jedi = False
322 ip.Completer.use_jedi = False
323 assert_in(Completion(start, end, comp), completions, reason)
323 assert_in(Completion(start, end, comp), completions, reason)
324
324
325 def _test_not_complete(reason, s, comp):
325 def _test_not_complete(reason, s, comp):
326 l = len(s)
326 l = len(s)
327 with provisionalcompleter():
327 with provisionalcompleter():
328 ip.Completer.use_jedi = True
328 ip.Completer.use_jedi = True
329 completions = set(ip.Completer.completions(s, l))
329 completions = set(ip.Completer.completions(s, l))
330 ip.Completer.use_jedi = False
330 ip.Completer.use_jedi = False
331 assert_not_in(Completion(l, l, comp), completions, reason)
331 assert_not_in(Completion(l, l, comp), completions, reason)
332
332
333 import jedi
333 import jedi
334 jedi_version = tuple(int(i) for i in jedi.__version__.split('.')[:3])
334 jedi_version = tuple(int(i) for i in jedi.__version__.split('.')[:3])
335 if jedi_version > (0, 10):
335 if jedi_version > (0, 10):
336 yield _test_complete, 'jedi >0.9 should complete and not crash', 'a=1;a.', 'real'
336 yield _test_complete, 'jedi >0.9 should complete and not crash', 'a=1;a.', 'real'
337 yield _test_complete, 'can infer first argument', 'a=(1,"foo");a[0].', 'real'
337 yield _test_complete, 'can infer first argument', 'a=(1,"foo");a[0].', 'real'
338 yield _test_complete, 'can infer second argument', 'a=(1,"foo");a[1].', 'capitalize'
338 yield _test_complete, 'can infer second argument', 'a=(1,"foo");a[1].', 'capitalize'
339 yield _test_complete, 'cover duplicate completions', 'im', 'import', 0, 2
339 yield _test_complete, 'cover duplicate completions', 'im', 'import', 0, 2
340
340
341 yield _test_not_complete, 'does not mix types', 'a=(1,"foo");a[0].', 'capitalize'
341 yield _test_not_complete, 'does not mix types', 'a=(1,"foo");a[0].', 'capitalize'
342
342
343 def test_completion_have_signature():
343 def test_completion_have_signature():
344 """
344 """
345 Lets make sure jedi is capable of pulling out the signature of the function we are completing.
345 Lets make sure jedi is capable of pulling out the signature of the function we are completing.
346 """
346 """
347 ip = get_ipython()
347 ip = get_ipython()
348 with provisionalcompleter():
348 with provisionalcompleter():
349 ip.Completer.use_jedi = True
349 ip.Completer.use_jedi = True
350 completions = ip.Completer.completions('ope', 3)
350 completions = ip.Completer.completions('ope', 3)
351 c = next(completions) # should be `open`
351 c = next(completions) # should be `open`
352 ip.Completer.use_jedi = False
352 ip.Completer.use_jedi = False
353 assert 'file' in c.signature, "Signature of function was not found by completer"
353 assert 'file' in c.signature, "Signature of function was not found by completer"
354 assert 'encoding' in c.signature, "Signature of function was not found by completer"
354 assert 'encoding' in c.signature, "Signature of function was not found by completer"
355
355
356
356
357 def test_deduplicate_completions():
357 def test_deduplicate_completions():
358 """
358 """
359 Test that completions are correctly deduplicated (even if ranges are not the same)
359 Test that completions are correctly deduplicated (even if ranges are not the same)
360 """
360 """
361 ip = get_ipython()
361 ip = get_ipython()
362 ip.ex(textwrap.dedent('''
362 ip.ex(textwrap.dedent('''
363 class Z:
363 class Z:
364 zoo = 1
364 zoo = 1
365 '''))
365 '''))
366 with provisionalcompleter():
366 with provisionalcompleter():
367 ip.Completer.use_jedi = True
367 ip.Completer.use_jedi = True
368 l = list(_deduplicate_completions('Z.z', ip.Completer.completions('Z.z', 3)))
368 l = list(_deduplicate_completions('Z.z', ip.Completer.completions('Z.z', 3)))
369 ip.Completer.use_jedi = False
369 ip.Completer.use_jedi = False
370
370
371 assert len(l) == 1, 'Completions (Z.z<tab>) correctly deduplicate: %s ' % l
371 assert len(l) == 1, 'Completions (Z.z<tab>) correctly deduplicate: %s ' % l
372 assert l[0].text == 'zoo' # and not `it.accumulate`
372 assert l[0].text == 'zoo' # and not `it.accumulate`
373
373
374
374
375 def test_greedy_completions():
375 def test_greedy_completions():
376 """
376 """
377 Test the capability of the Greedy completer.
377 Test the capability of the Greedy completer.
378
378
379 Most of the test here does not really show off the greedy completer, for proof
379 Most of the test here does not really show off the greedy completer, for proof
380 each of the text below now pass with Jedi. The greedy completer is capable of more.
380 each of the text below now pass with Jedi. The greedy completer is capable of more.
381
381
382 See the :any:`test_dict_key_completion_contexts`
382 See the :any:`test_dict_key_completion_contexts`
383
383
384 """
384 """
385 ip = get_ipython()
385 ip = get_ipython()
386 ip.ex('a=list(range(5))')
386 ip.ex('a=list(range(5))')
387 _,c = ip.complete('.',line='a[0].')
387 _,c = ip.complete('.',line='a[0].')
388 nt.assert_false('.real' in c,
388 nt.assert_false('.real' in c,
389 "Shouldn't have completed on a[0]: %s"%c)
389 "Shouldn't have completed on a[0]: %s"%c)
390 with greedy_completion(), provisionalcompleter():
390 def _(line, cursor_pos, expect, message, completion):
391 def _(line, cursor_pos, expect, message, completion):
391 with greedy_completion(), provisionalcompleter():
392 ip.Completer.use_jedi = False
392 ip.Completer.use_jedi = False
393 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
393 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
394 nt.assert_in(expect, c, message % c)
394 nt.assert_in(expect, c, message % c)
395
395
396 ip.Completer.use_jedi = True
396 ip.Completer.use_jedi = True
397 with provisionalcompleter():
397 with provisionalcompleter():
398 completions = ip.Completer.completions(line, cursor_pos)
398 completions = ip.Completer.completions(line, cursor_pos)
399 nt.assert_in(completion, completions)
399 nt.assert_in(completion, completions)
400
400
401 with provisionalcompleter():
401 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s", Completion(5,5, 'real')
402 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s", Completion(5,5, 'real')
402 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s", Completion(5,6, 'real')
403 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s", Completion(5,6, 'real')
403
404
404 if sys.version_info > (3, 4):
405 if sys.version_info > (3, 4):
405 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s", Completion(5, 10, 'from_bytes')
406 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s", Completion(5, 10, 'from_bytes')
406
407
407
408
408 def test_omit__names():
409 def test_omit__names():
409 # also happens to test IPCompleter as a configurable
410 # also happens to test IPCompleter as a configurable
410 ip = get_ipython()
411 ip = get_ipython()
411 ip._hidden_attr = 1
412 ip._hidden_attr = 1
412 ip._x = {}
413 ip._x = {}
413 c = ip.Completer
414 c = ip.Completer
414 ip.ex('ip=get_ipython()')
415 ip.ex('ip=get_ipython()')
415 cfg = Config()
416 cfg = Config()
416 cfg.IPCompleter.omit__names = 0
417 cfg.IPCompleter.omit__names = 0
417 c.update_config(cfg)
418 c.update_config(cfg)
418 with provisionalcompleter():
419 with provisionalcompleter():
419 c.use_jedi = False
420 c.use_jedi = False
420 s,matches = c.complete('ip.')
421 s,matches = c.complete('ip.')
421 nt.assert_in('ip.__str__', matches)
422 nt.assert_in('ip.__str__', matches)
422 nt.assert_in('ip._hidden_attr', matches)
423 nt.assert_in('ip._hidden_attr', matches)
423
424
424 # c.use_jedi = True
425 # c.use_jedi = True
425 # completions = set(c.completions('ip.', 3))
426 # completions = set(c.completions('ip.', 3))
426 # nt.assert_in(Completion(3, 3, '__str__'), completions)
427 # nt.assert_in(Completion(3, 3, '__str__'), completions)
427 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
428 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
428
429
429
430
430 cfg = Config()
431 cfg = Config()
431 cfg.IPCompleter.omit__names = 1
432 cfg.IPCompleter.omit__names = 1
432 c.update_config(cfg)
433 c.update_config(cfg)
433 with provisionalcompleter():
434 with provisionalcompleter():
434 c.use_jedi = False
435 c.use_jedi = False
435 s,matches = c.complete('ip.')
436 s,matches = c.complete('ip.')
436 nt.assert_not_in('ip.__str__', matches)
437 nt.assert_not_in('ip.__str__', matches)
437 # nt.assert_in('ip._hidden_attr', matches)
438 # nt.assert_in('ip._hidden_attr', matches)
438
439
439 # c.use_jedi = True
440 # c.use_jedi = True
440 # completions = set(c.completions('ip.', 3))
441 # completions = set(c.completions('ip.', 3))
441 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
442 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
442 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
443 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
443
444
444 cfg = Config()
445 cfg = Config()
445 cfg.IPCompleter.omit__names = 2
446 cfg.IPCompleter.omit__names = 2
446 c.update_config(cfg)
447 c.update_config(cfg)
447 with provisionalcompleter():
448 with provisionalcompleter():
448 c.use_jedi = False
449 c.use_jedi = False
449 s,matches = c.complete('ip.')
450 s,matches = c.complete('ip.')
450 nt.assert_not_in('ip.__str__', matches)
451 nt.assert_not_in('ip.__str__', matches)
451 nt.assert_not_in('ip._hidden_attr', matches)
452 nt.assert_not_in('ip._hidden_attr', matches)
452
453
453 # c.use_jedi = True
454 # c.use_jedi = True
454 # completions = set(c.completions('ip.', 3))
455 # completions = set(c.completions('ip.', 3))
455 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
456 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
456 # nt.assert_not_in(Completion(3,3, "_hidden_attr"), completions)
457 # nt.assert_not_in(Completion(3,3, "_hidden_attr"), completions)
457
458
458 with provisionalcompleter():
459 with provisionalcompleter():
459 c.use_jedi = False
460 c.use_jedi = False
460 s,matches = c.complete('ip._x.')
461 s,matches = c.complete('ip._x.')
461 nt.assert_in('ip._x.keys', matches)
462 nt.assert_in('ip._x.keys', matches)
462
463
463 # c.use_jedi = True
464 # c.use_jedi = True
464 # completions = set(c.completions('ip._x.', 6))
465 # completions = set(c.completions('ip._x.', 6))
465 # nt.assert_in(Completion(6,6, "keys"), completions)
466 # nt.assert_in(Completion(6,6, "keys"), completions)
466
467
467 del ip._hidden_attr
468 del ip._hidden_attr
468 del ip._x
469 del ip._x
469
470
470
471
471 def test_limit_to__all__False_ok():
472 def test_limit_to__all__False_ok():
472 """
473 """
473 Limit to all is deprecated, once we remove it this test can go away.
474 Limit to all is deprecated, once we remove it this test can go away.
474 """
475 """
475 ip = get_ipython()
476 ip = get_ipython()
476 c = ip.Completer
477 c = ip.Completer
477 c.use_jedi = False
478 c.use_jedi = False
478 ip.ex('class D: x=24')
479 ip.ex('class D: x=24')
479 ip.ex('d=D()')
480 ip.ex('d=D()')
480 cfg = Config()
481 cfg = Config()
481 cfg.IPCompleter.limit_to__all__ = False
482 cfg.IPCompleter.limit_to__all__ = False
482 c.update_config(cfg)
483 c.update_config(cfg)
483 s, matches = c.complete('d.')
484 s, matches = c.complete('d.')
484 nt.assert_in('d.x', matches)
485 nt.assert_in('d.x', matches)
485
486
486
487
487 def test_get__all__entries_ok():
488 def test_get__all__entries_ok():
488 class A(object):
489 class A(object):
489 __all__ = ['x', 1]
490 __all__ = ['x', 1]
490 words = completer.get__all__entries(A())
491 words = completer.get__all__entries(A())
491 nt.assert_equal(words, ['x'])
492 nt.assert_equal(words, ['x'])
492
493
493
494
494 def test_get__all__entries_no__all__ok():
495 def test_get__all__entries_no__all__ok():
495 class A(object):
496 class A(object):
496 pass
497 pass
497 words = completer.get__all__entries(A())
498 words = completer.get__all__entries(A())
498 nt.assert_equal(words, [])
499 nt.assert_equal(words, [])
499
500
500
501
501 def test_func_kw_completions():
502 def test_func_kw_completions():
502 ip = get_ipython()
503 ip = get_ipython()
503 c = ip.Completer
504 c = ip.Completer
504 c.use_jedi = False
505 c.use_jedi = False
505 ip.ex('def myfunc(a=1,b=2): return a+b')
506 ip.ex('def myfunc(a=1,b=2): return a+b')
506 s, matches = c.complete(None, 'myfunc(1,b')
507 s, matches = c.complete(None, 'myfunc(1,b')
507 nt.assert_in('b=', matches)
508 nt.assert_in('b=', matches)
508 # Simulate completing with cursor right after b (pos==10):
509 # Simulate completing with cursor right after b (pos==10):
509 s, matches = c.complete(None, 'myfunc(1,b)', 10)
510 s, matches = c.complete(None, 'myfunc(1,b)', 10)
510 nt.assert_in('b=', matches)
511 nt.assert_in('b=', matches)
511 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
512 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
512 nt.assert_in('b=', matches)
513 nt.assert_in('b=', matches)
513 #builtin function
514 #builtin function
514 s, matches = c.complete(None, 'min(k, k')
515 s, matches = c.complete(None, 'min(k, k')
515 nt.assert_in('key=', matches)
516 nt.assert_in('key=', matches)
516
517
517
518
518 def test_default_arguments_from_docstring():
519 def test_default_arguments_from_docstring():
519 ip = get_ipython()
520 ip = get_ipython()
520 c = ip.Completer
521 c = ip.Completer
521 kwd = c._default_arguments_from_docstring(
522 kwd = c._default_arguments_from_docstring(
522 'min(iterable[, key=func]) -> value')
523 'min(iterable[, key=func]) -> value')
523 nt.assert_equal(kwd, ['key'])
524 nt.assert_equal(kwd, ['key'])
524 #with cython type etc
525 #with cython type etc
525 kwd = c._default_arguments_from_docstring(
526 kwd = c._default_arguments_from_docstring(
526 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
527 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
527 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
528 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
528 #white spaces
529 #white spaces
529 kwd = c._default_arguments_from_docstring(
530 kwd = c._default_arguments_from_docstring(
530 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
531 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
531 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
532 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
532
533
533 def test_line_magics():
534 def test_line_magics():
534 ip = get_ipython()
535 ip = get_ipython()
535 c = ip.Completer
536 c = ip.Completer
536 s, matches = c.complete(None, 'lsmag')
537 s, matches = c.complete(None, 'lsmag')
537 nt.assert_in('%lsmagic', matches)
538 nt.assert_in('%lsmagic', matches)
538 s, matches = c.complete(None, '%lsmag')
539 s, matches = c.complete(None, '%lsmag')
539 nt.assert_in('%lsmagic', matches)
540 nt.assert_in('%lsmagic', matches)
540
541
541
542
542 def test_cell_magics():
543 def test_cell_magics():
543 from IPython.core.magic import register_cell_magic
544 from IPython.core.magic import register_cell_magic
544
545
545 @register_cell_magic
546 @register_cell_magic
546 def _foo_cellm(line, cell):
547 def _foo_cellm(line, cell):
547 pass
548 pass
548
549
549 ip = get_ipython()
550 ip = get_ipython()
550 c = ip.Completer
551 c = ip.Completer
551
552
552 s, matches = c.complete(None, '_foo_ce')
553 s, matches = c.complete(None, '_foo_ce')
553 nt.assert_in('%%_foo_cellm', matches)
554 nt.assert_in('%%_foo_cellm', matches)
554 s, matches = c.complete(None, '%%_foo_ce')
555 s, matches = c.complete(None, '%%_foo_ce')
555 nt.assert_in('%%_foo_cellm', matches)
556 nt.assert_in('%%_foo_cellm', matches)
556
557
557
558
558 def test_line_cell_magics():
559 def test_line_cell_magics():
559 from IPython.core.magic import register_line_cell_magic
560 from IPython.core.magic import register_line_cell_magic
560
561
561 @register_line_cell_magic
562 @register_line_cell_magic
562 def _bar_cellm(line, cell):
563 def _bar_cellm(line, cell):
563 pass
564 pass
564
565
565 ip = get_ipython()
566 ip = get_ipython()
566 c = ip.Completer
567 c = ip.Completer
567
568
568 # The policy here is trickier, see comments in completion code. The
569 # The policy here is trickier, see comments in completion code. The
569 # returned values depend on whether the user passes %% or not explicitly,
570 # returned values depend on whether the user passes %% or not explicitly,
570 # and this will show a difference if the same name is both a line and cell
571 # and this will show a difference if the same name is both a line and cell
571 # magic.
572 # magic.
572 s, matches = c.complete(None, '_bar_ce')
573 s, matches = c.complete(None, '_bar_ce')
573 nt.assert_in('%_bar_cellm', matches)
574 nt.assert_in('%_bar_cellm', matches)
574 nt.assert_in('%%_bar_cellm', matches)
575 nt.assert_in('%%_bar_cellm', matches)
575 s, matches = c.complete(None, '%_bar_ce')
576 s, matches = c.complete(None, '%_bar_ce')
576 nt.assert_in('%_bar_cellm', matches)
577 nt.assert_in('%_bar_cellm', matches)
577 nt.assert_in('%%_bar_cellm', matches)
578 nt.assert_in('%%_bar_cellm', matches)
578 s, matches = c.complete(None, '%%_bar_ce')
579 s, matches = c.complete(None, '%%_bar_ce')
579 nt.assert_not_in('%_bar_cellm', matches)
580 nt.assert_not_in('%_bar_cellm', matches)
580 nt.assert_in('%%_bar_cellm', matches)
581 nt.assert_in('%%_bar_cellm', matches)
581
582
582
583
583 def test_magic_completion_order():
584 def test_magic_completion_order():
584 ip = get_ipython()
585 ip = get_ipython()
585 c = ip.Completer
586 c = ip.Completer
586
587
587 # Test ordering of line and cell magics.
588 # Test ordering of line and cell magics.
588 text, matches = c.complete("timeit")
589 text, matches = c.complete("timeit")
589 nt.assert_equal(matches, ["%timeit", "%%timeit"])
590 nt.assert_equal(matches, ["%timeit", "%%timeit"])
590
591
591
592
592 def test_magic_completion_shadowing():
593 def test_magic_completion_shadowing():
593 ip = get_ipython()
594 ip = get_ipython()
594 c = ip.Completer
595 c = ip.Completer
595 c.use_jedi = False
596 c.use_jedi = False
596
597
597 # Before importing matplotlib, %matplotlib magic should be the only option.
598 # Before importing matplotlib, %matplotlib magic should be the only option.
598 text, matches = c.complete("mat")
599 text, matches = c.complete("mat")
599 nt.assert_equal(matches, ["%matplotlib"])
600 nt.assert_equal(matches, ["%matplotlib"])
600
601
601 # The newly introduced name should shadow the magic.
602 # The newly introduced name should shadow the magic.
602 ip.run_cell("matplotlib = 1")
603 ip.run_cell("matplotlib = 1")
603 text, matches = c.complete("mat")
604 text, matches = c.complete("mat")
604 nt.assert_equal(matches, ["matplotlib"])
605 nt.assert_equal(matches, ["matplotlib"])
605
606
606 # After removing matplotlib from namespace, the magic should again be
607 # After removing matplotlib from namespace, the magic should again be
607 # the only option.
608 # the only option.
608 del ip.user_ns["matplotlib"]
609 del ip.user_ns["matplotlib"]
609 text, matches = c.complete("mat")
610 text, matches = c.complete("mat")
610 nt.assert_equal(matches, ["%matplotlib"])
611 nt.assert_equal(matches, ["%matplotlib"])
611
612
612 def test_magic_completion_shadowing_explicit():
613 def test_magic_completion_shadowing_explicit():
613 """
614 """
614 If the user try to complete a shadowed magic, and explicit % start should
615 If the user try to complete a shadowed magic, and explicit % start should
615 still return the completions.
616 still return the completions.
616 """
617 """
617 ip = get_ipython()
618 ip = get_ipython()
618 c = ip.Completer
619 c = ip.Completer
619
620
620 # Before importing matplotlib, %matplotlib magic should be the only option.
621 # Before importing matplotlib, %matplotlib magic should be the only option.
621 text, matches = c.complete("%mat")
622 text, matches = c.complete("%mat")
622 nt.assert_equal(matches, ["%matplotlib"])
623 nt.assert_equal(matches, ["%matplotlib"])
623
624
624 ip.run_cell("matplotlib = 1")
625 ip.run_cell("matplotlib = 1")
625
626
626 # After removing matplotlib from namespace, the magic should still be
627 # After removing matplotlib from namespace, the magic should still be
627 # the only option.
628 # the only option.
628 text, matches = c.complete("%mat")
629 text, matches = c.complete("%mat")
629 nt.assert_equal(matches, ["%matplotlib"])
630 nt.assert_equal(matches, ["%matplotlib"])
630
631
631 def test_magic_config():
632 def test_magic_config():
632 ip = get_ipython()
633 ip = get_ipython()
633 c = ip.Completer
634 c = ip.Completer
634
635
635 s, matches = c.complete(None, 'conf')
636 s, matches = c.complete(None, 'conf')
636 nt.assert_in('%config', matches)
637 nt.assert_in('%config', matches)
637 s, matches = c.complete(None, 'conf')
638 s, matches = c.complete(None, 'conf')
638 nt.assert_not_in('AliasManager', matches)
639 nt.assert_not_in('AliasManager', matches)
639 s, matches = c.complete(None, 'config ')
640 s, matches = c.complete(None, 'config ')
640 nt.assert_in('AliasManager', matches)
641 nt.assert_in('AliasManager', matches)
641 s, matches = c.complete(None, '%config ')
642 s, matches = c.complete(None, '%config ')
642 nt.assert_in('AliasManager', matches)
643 nt.assert_in('AliasManager', matches)
643 s, matches = c.complete(None, 'config Ali')
644 s, matches = c.complete(None, 'config Ali')
644 nt.assert_list_equal(['AliasManager'], matches)
645 nt.assert_list_equal(['AliasManager'], matches)
645 s, matches = c.complete(None, '%config Ali')
646 s, matches = c.complete(None, '%config Ali')
646 nt.assert_list_equal(['AliasManager'], matches)
647 nt.assert_list_equal(['AliasManager'], matches)
647 s, matches = c.complete(None, 'config AliasManager')
648 s, matches = c.complete(None, 'config AliasManager')
648 nt.assert_list_equal(['AliasManager'], matches)
649 nt.assert_list_equal(['AliasManager'], matches)
649 s, matches = c.complete(None, '%config AliasManager')
650 s, matches = c.complete(None, '%config AliasManager')
650 nt.assert_list_equal(['AliasManager'], matches)
651 nt.assert_list_equal(['AliasManager'], matches)
651 s, matches = c.complete(None, 'config AliasManager.')
652 s, matches = c.complete(None, 'config AliasManager.')
652 nt.assert_in('AliasManager.default_aliases', matches)
653 nt.assert_in('AliasManager.default_aliases', matches)
653 s, matches = c.complete(None, '%config AliasManager.')
654 s, matches = c.complete(None, '%config AliasManager.')
654 nt.assert_in('AliasManager.default_aliases', matches)
655 nt.assert_in('AliasManager.default_aliases', matches)
655 s, matches = c.complete(None, 'config AliasManager.de')
656 s, matches = c.complete(None, 'config AliasManager.de')
656 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
657 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
657 s, matches = c.complete(None, 'config AliasManager.de')
658 s, matches = c.complete(None, 'config AliasManager.de')
658 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
659 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
659
660
660
661
661 def test_magic_color():
662 def test_magic_color():
662 ip = get_ipython()
663 ip = get_ipython()
663 c = ip.Completer
664 c = ip.Completer
664
665
665 s, matches = c.complete(None, 'colo')
666 s, matches = c.complete(None, 'colo')
666 nt.assert_in('%colors', matches)
667 nt.assert_in('%colors', matches)
667 s, matches = c.complete(None, 'colo')
668 s, matches = c.complete(None, 'colo')
668 nt.assert_not_in('NoColor', matches)
669 nt.assert_not_in('NoColor', matches)
669 s, matches = c.complete(None, '%colors') # No trailing space
670 s, matches = c.complete(None, '%colors') # No trailing space
670 nt.assert_not_in('NoColor', matches)
671 nt.assert_not_in('NoColor', matches)
671 s, matches = c.complete(None, 'colors ')
672 s, matches = c.complete(None, 'colors ')
672 nt.assert_in('NoColor', matches)
673 nt.assert_in('NoColor', matches)
673 s, matches = c.complete(None, '%colors ')
674 s, matches = c.complete(None, '%colors ')
674 nt.assert_in('NoColor', matches)
675 nt.assert_in('NoColor', matches)
675 s, matches = c.complete(None, 'colors NoCo')
676 s, matches = c.complete(None, 'colors NoCo')
676 nt.assert_list_equal(['NoColor'], matches)
677 nt.assert_list_equal(['NoColor'], matches)
677 s, matches = c.complete(None, '%colors NoCo')
678 s, matches = c.complete(None, '%colors NoCo')
678 nt.assert_list_equal(['NoColor'], matches)
679 nt.assert_list_equal(['NoColor'], matches)
679
680
680
681
681 def test_match_dict_keys():
682 def test_match_dict_keys():
682 """
683 """
683 Test that match_dict_keys works on a couple of use case does return what
684 Test that match_dict_keys works on a couple of use case does return what
684 expected, and does not crash
685 expected, and does not crash
685 """
686 """
686 delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
687 delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
687
688
688
689
689 keys = ['foo', b'far']
690 keys = ['foo', b'far']
690 assert match_dict_keys(keys, "b'", delims=delims) == ("'", 2 ,['far'])
691 assert match_dict_keys(keys, "b'", delims=delims) == ("'", 2 ,['far'])
691 assert match_dict_keys(keys, "b'f", delims=delims) == ("'", 2 ,['far'])
692 assert match_dict_keys(keys, "b'f", delims=delims) == ("'", 2 ,['far'])
692 assert match_dict_keys(keys, 'b"', delims=delims) == ('"', 2 ,['far'])
693 assert match_dict_keys(keys, 'b"', delims=delims) == ('"', 2 ,['far'])
693 assert match_dict_keys(keys, 'b"f', delims=delims) == ('"', 2 ,['far'])
694 assert match_dict_keys(keys, 'b"f', delims=delims) == ('"', 2 ,['far'])
694
695
695 assert match_dict_keys(keys, "'", delims=delims) == ("'", 1 ,['foo'])
696 assert match_dict_keys(keys, "'", delims=delims) == ("'", 1 ,['foo'])
696 assert match_dict_keys(keys, "'f", delims=delims) == ("'", 1 ,['foo'])
697 assert match_dict_keys(keys, "'f", delims=delims) == ("'", 1 ,['foo'])
697 assert match_dict_keys(keys, '"', delims=delims) == ('"', 1 ,['foo'])
698 assert match_dict_keys(keys, '"', delims=delims) == ('"', 1 ,['foo'])
698 assert match_dict_keys(keys, '"f', delims=delims) == ('"', 1 ,['foo'])
699 assert match_dict_keys(keys, '"f', delims=delims) == ('"', 1 ,['foo'])
699
700
700 match_dict_keys
701 match_dict_keys
701
702
702
703
703 def test_dict_key_completion_string():
704 def test_dict_key_completion_string():
704 """Test dictionary key completion for string keys"""
705 """Test dictionary key completion for string keys"""
705 ip = get_ipython()
706 ip = get_ipython()
706 complete = ip.Completer.complete
707 complete = ip.Completer.complete
707
708
708 ip.user_ns['d'] = {'abc': None}
709 ip.user_ns['d'] = {'abc': None}
709
710
710 # check completion at different stages
711 # check completion at different stages
711 _, matches = complete(line_buffer="d[")
712 _, matches = complete(line_buffer="d[")
712 nt.assert_in("'abc'", matches)
713 nt.assert_in("'abc'", matches)
713 nt.assert_not_in("'abc']", matches)
714 nt.assert_not_in("'abc']", matches)
714
715
715 _, matches = complete(line_buffer="d['")
716 _, matches = complete(line_buffer="d['")
716 nt.assert_in("abc", matches)
717 nt.assert_in("abc", matches)
717 nt.assert_not_in("abc']", matches)
718 nt.assert_not_in("abc']", matches)
718
719
719 _, matches = complete(line_buffer="d['a")
720 _, matches = complete(line_buffer="d['a")
720 nt.assert_in("abc", matches)
721 nt.assert_in("abc", matches)
721 nt.assert_not_in("abc']", matches)
722 nt.assert_not_in("abc']", matches)
722
723
723 # check use of different quoting
724 # check use of different quoting
724 _, matches = complete(line_buffer="d[\"")
725 _, matches = complete(line_buffer="d[\"")
725 nt.assert_in("abc", matches)
726 nt.assert_in("abc", matches)
726 nt.assert_not_in('abc\"]', matches)
727 nt.assert_not_in('abc\"]', matches)
727
728
728 _, matches = complete(line_buffer="d[\"a")
729 _, matches = complete(line_buffer="d[\"a")
729 nt.assert_in("abc", matches)
730 nt.assert_in("abc", matches)
730 nt.assert_not_in('abc\"]', matches)
731 nt.assert_not_in('abc\"]', matches)
731
732
732 # check sensitivity to following context
733 # check sensitivity to following context
733 _, matches = complete(line_buffer="d[]", cursor_pos=2)
734 _, matches = complete(line_buffer="d[]", cursor_pos=2)
734 nt.assert_in("'abc'", matches)
735 nt.assert_in("'abc'", matches)
735
736
736 _, matches = complete(line_buffer="d['']", cursor_pos=3)
737 _, matches = complete(line_buffer="d['']", cursor_pos=3)
737 nt.assert_in("abc", matches)
738 nt.assert_in("abc", matches)
738 nt.assert_not_in("abc'", matches)
739 nt.assert_not_in("abc'", matches)
739 nt.assert_not_in("abc']", matches)
740 nt.assert_not_in("abc']", matches)
740
741
741 # check multiple solutions are correctly returned and that noise is not
742 # check multiple solutions are correctly returned and that noise is not
742 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
743 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
743 5: None}
744 5: None}
744
745
745 _, matches = complete(line_buffer="d['a")
746 _, matches = complete(line_buffer="d['a")
746 nt.assert_in("abc", matches)
747 nt.assert_in("abc", matches)
747 nt.assert_in("abd", matches)
748 nt.assert_in("abd", matches)
748 nt.assert_not_in("bad", matches)
749 nt.assert_not_in("bad", matches)
749 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
750 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
750
751
751 # check escaping and whitespace
752 # check escaping and whitespace
752 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
753 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
753 _, matches = complete(line_buffer="d['a")
754 _, matches = complete(line_buffer="d['a")
754 nt.assert_in("a\\nb", matches)
755 nt.assert_in("a\\nb", matches)
755 nt.assert_in("a\\'b", matches)
756 nt.assert_in("a\\'b", matches)
756 nt.assert_in("a\"b", matches)
757 nt.assert_in("a\"b", matches)
757 nt.assert_in("a word", matches)
758 nt.assert_in("a word", matches)
758 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
759 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
759
760
760 # - can complete on non-initial word of the string
761 # - can complete on non-initial word of the string
761 _, matches = complete(line_buffer="d['a w")
762 _, matches = complete(line_buffer="d['a w")
762 nt.assert_in("word", matches)
763 nt.assert_in("word", matches)
763
764
764 # - understands quote escaping
765 # - understands quote escaping
765 _, matches = complete(line_buffer="d['a\\'")
766 _, matches = complete(line_buffer="d['a\\'")
766 nt.assert_in("b", matches)
767 nt.assert_in("b", matches)
767
768
768 # - default quoting should work like repr
769 # - default quoting should work like repr
769 _, matches = complete(line_buffer="d[")
770 _, matches = complete(line_buffer="d[")
770 nt.assert_in("\"a'b\"", matches)
771 nt.assert_in("\"a'b\"", matches)
771
772
772 # - when opening quote with ", possible to match with unescaped apostrophe
773 # - when opening quote with ", possible to match with unescaped apostrophe
773 _, matches = complete(line_buffer="d[\"a'")
774 _, matches = complete(line_buffer="d[\"a'")
774 nt.assert_in("b", matches)
775 nt.assert_in("b", matches)
775
776
776 # need to not split at delims that readline won't split at
777 # need to not split at delims that readline won't split at
777 if '-' not in ip.Completer.splitter.delims:
778 if '-' not in ip.Completer.splitter.delims:
778 ip.user_ns['d'] = {'before-after': None}
779 ip.user_ns['d'] = {'before-after': None}
779 _, matches = complete(line_buffer="d['before-af")
780 _, matches = complete(line_buffer="d['before-af")
780 nt.assert_in('before-after', matches)
781 nt.assert_in('before-after', matches)
781
782
782 def test_dict_key_completion_contexts():
783 def test_dict_key_completion_contexts():
783 """Test expression contexts in which dict key completion occurs"""
784 """Test expression contexts in which dict key completion occurs"""
784 ip = get_ipython()
785 ip = get_ipython()
785 complete = ip.Completer.complete
786 complete = ip.Completer.complete
786 d = {'abc': None}
787 d = {'abc': None}
787 ip.user_ns['d'] = d
788 ip.user_ns['d'] = d
788
789
789 class C:
790 class C:
790 data = d
791 data = d
791 ip.user_ns['C'] = C
792 ip.user_ns['C'] = C
792 ip.user_ns['get'] = lambda: d
793 ip.user_ns['get'] = lambda: d
793
794
794 def assert_no_completion(**kwargs):
795 def assert_no_completion(**kwargs):
795 _, matches = complete(**kwargs)
796 _, matches = complete(**kwargs)
796 nt.assert_not_in('abc', matches)
797 nt.assert_not_in('abc', matches)
797 nt.assert_not_in('abc\'', matches)
798 nt.assert_not_in('abc\'', matches)
798 nt.assert_not_in('abc\']', matches)
799 nt.assert_not_in('abc\']', matches)
799 nt.assert_not_in('\'abc\'', matches)
800 nt.assert_not_in('\'abc\'', matches)
800 nt.assert_not_in('\'abc\']', matches)
801 nt.assert_not_in('\'abc\']', matches)
801
802
802 def assert_completion(**kwargs):
803 def assert_completion(**kwargs):
803 _, matches = complete(**kwargs)
804 _, matches = complete(**kwargs)
804 nt.assert_in("'abc'", matches)
805 nt.assert_in("'abc'", matches)
805 nt.assert_not_in("'abc']", matches)
806 nt.assert_not_in("'abc']", matches)
806
807
807 # no completion after string closed, even if reopened
808 # no completion after string closed, even if reopened
808 assert_no_completion(line_buffer="d['a'")
809 assert_no_completion(line_buffer="d['a'")
809 assert_no_completion(line_buffer="d[\"a\"")
810 assert_no_completion(line_buffer="d[\"a\"")
810 assert_no_completion(line_buffer="d['a' + ")
811 assert_no_completion(line_buffer="d['a' + ")
811 assert_no_completion(line_buffer="d['a' + '")
812 assert_no_completion(line_buffer="d['a' + '")
812
813
813 # completion in non-trivial expressions
814 # completion in non-trivial expressions
814 assert_completion(line_buffer="+ d[")
815 assert_completion(line_buffer="+ d[")
815 assert_completion(line_buffer="(d[")
816 assert_completion(line_buffer="(d[")
816 assert_completion(line_buffer="C.data[")
817 assert_completion(line_buffer="C.data[")
817
818
818 # greedy flag
819 # greedy flag
819 def assert_completion(**kwargs):
820 def assert_completion(**kwargs):
820 _, matches = complete(**kwargs)
821 _, matches = complete(**kwargs)
821 nt.assert_in("get()['abc']", matches)
822 nt.assert_in("get()['abc']", matches)
822
823
823 assert_no_completion(line_buffer="get()[")
824 assert_no_completion(line_buffer="get()[")
824 with greedy_completion():
825 with greedy_completion():
825 assert_completion(line_buffer="get()[")
826 assert_completion(line_buffer="get()[")
826 assert_completion(line_buffer="get()['")
827 assert_completion(line_buffer="get()['")
827 assert_completion(line_buffer="get()['a")
828 assert_completion(line_buffer="get()['a")
828 assert_completion(line_buffer="get()['ab")
829 assert_completion(line_buffer="get()['ab")
829 assert_completion(line_buffer="get()['abc")
830 assert_completion(line_buffer="get()['abc")
830
831
831
832
832
833
833 def test_dict_key_completion_bytes():
834 def test_dict_key_completion_bytes():
834 """Test handling of bytes in dict key completion"""
835 """Test handling of bytes in dict key completion"""
835 ip = get_ipython()
836 ip = get_ipython()
836 complete = ip.Completer.complete
837 complete = ip.Completer.complete
837
838
838 ip.user_ns['d'] = {'abc': None, b'abd': None}
839 ip.user_ns['d'] = {'abc': None, b'abd': None}
839
840
840 _, matches = complete(line_buffer="d[")
841 _, matches = complete(line_buffer="d[")
841 nt.assert_in("'abc'", matches)
842 nt.assert_in("'abc'", matches)
842 nt.assert_in("b'abd'", matches)
843 nt.assert_in("b'abd'", matches)
843
844
844 if False: # not currently implemented
845 if False: # not currently implemented
845 _, matches = complete(line_buffer="d[b")
846 _, matches = complete(line_buffer="d[b")
846 nt.assert_in("b'abd'", matches)
847 nt.assert_in("b'abd'", matches)
847 nt.assert_not_in("b'abc'", matches)
848 nt.assert_not_in("b'abc'", matches)
848
849
849 _, matches = complete(line_buffer="d[b'")
850 _, matches = complete(line_buffer="d[b'")
850 nt.assert_in("abd", matches)
851 nt.assert_in("abd", matches)
851 nt.assert_not_in("abc", matches)
852 nt.assert_not_in("abc", matches)
852
853
853 _, matches = complete(line_buffer="d[B'")
854 _, matches = complete(line_buffer="d[B'")
854 nt.assert_in("abd", matches)
855 nt.assert_in("abd", matches)
855 nt.assert_not_in("abc", matches)
856 nt.assert_not_in("abc", matches)
856
857
857 _, matches = complete(line_buffer="d['")
858 _, matches = complete(line_buffer="d['")
858 nt.assert_in("abc", matches)
859 nt.assert_in("abc", matches)
859 nt.assert_not_in("abd", matches)
860 nt.assert_not_in("abd", matches)
860
861
861
862
862 def test_dict_key_completion_unicode_py3():
863 def test_dict_key_completion_unicode_py3():
863 """Test handling of unicode in dict key completion"""
864 """Test handling of unicode in dict key completion"""
864 ip = get_ipython()
865 ip = get_ipython()
865 complete = ip.Completer.complete
866 complete = ip.Completer.complete
866
867
867 ip.user_ns['d'] = {u'a\u05d0': None}
868 ip.user_ns['d'] = {u'a\u05d0': None}
868
869
869 # query using escape
870 # query using escape
870 if sys.platform != 'win32':
871 if sys.platform != 'win32':
871 # Known failure on Windows
872 # Known failure on Windows
872 _, matches = complete(line_buffer="d['a\\u05d0")
873 _, matches = complete(line_buffer="d['a\\u05d0")
873 nt.assert_in("u05d0", matches) # tokenized after \\
874 nt.assert_in("u05d0", matches) # tokenized after \\
874
875
875 # query using character
876 # query using character
876 _, matches = complete(line_buffer="d['a\u05d0")
877 _, matches = complete(line_buffer="d['a\u05d0")
877 nt.assert_in(u"a\u05d0", matches)
878 nt.assert_in(u"a\u05d0", matches)
878
879
879 with greedy_completion():
880 with greedy_completion():
880 # query using escape
881 # query using escape
881 _, matches = complete(line_buffer="d['a\\u05d0")
882 _, matches = complete(line_buffer="d['a\\u05d0")
882 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
883 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
883
884
884 # query using character
885 # query using character
885 _, matches = complete(line_buffer="d['a\u05d0")
886 _, matches = complete(line_buffer="d['a\u05d0")
886 nt.assert_in(u"d['a\u05d0']", matches)
887 nt.assert_in(u"d['a\u05d0']", matches)
887
888
888
889
889
890
890 @dec.skip_without('numpy')
891 @dec.skip_without('numpy')
891 def test_struct_array_key_completion():
892 def test_struct_array_key_completion():
892 """Test dict key completion applies to numpy struct arrays"""
893 """Test dict key completion applies to numpy struct arrays"""
893 import numpy
894 import numpy
894 ip = get_ipython()
895 ip = get_ipython()
895 complete = ip.Completer.complete
896 complete = ip.Completer.complete
896 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
897 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
897 _, matches = complete(line_buffer="d['")
898 _, matches = complete(line_buffer="d['")
898 nt.assert_in("hello", matches)
899 nt.assert_in("hello", matches)
899 nt.assert_in("world", matches)
900 nt.assert_in("world", matches)
900 # complete on the numpy struct itself
901 # complete on the numpy struct itself
901 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
902 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
902 ('my_data', '>f4', 5)])
903 ('my_data', '>f4', 5)])
903 x = numpy.zeros(2, dtype=dt)
904 x = numpy.zeros(2, dtype=dt)
904 ip.user_ns['d'] = x[1]
905 ip.user_ns['d'] = x[1]
905 _, matches = complete(line_buffer="d['")
906 _, matches = complete(line_buffer="d['")
906 nt.assert_in("my_head", matches)
907 nt.assert_in("my_head", matches)
907 nt.assert_in("my_data", matches)
908 nt.assert_in("my_data", matches)
908 # complete on a nested level
909 # complete on a nested level
909 with greedy_completion():
910 with greedy_completion():
910 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
911 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
911 _, matches = complete(line_buffer="d[1]['my_head']['")
912 _, matches = complete(line_buffer="d[1]['my_head']['")
912 nt.assert_true(any(["my_dt" in m for m in matches]))
913 nt.assert_true(any(["my_dt" in m for m in matches]))
913 nt.assert_true(any(["my_df" in m for m in matches]))
914 nt.assert_true(any(["my_df" in m for m in matches]))
914
915
915
916
916 @dec.skip_without('pandas')
917 @dec.skip_without('pandas')
917 def test_dataframe_key_completion():
918 def test_dataframe_key_completion():
918 """Test dict key completion applies to pandas DataFrames"""
919 """Test dict key completion applies to pandas DataFrames"""
919 import pandas
920 import pandas
920 ip = get_ipython()
921 ip = get_ipython()
921 complete = ip.Completer.complete
922 complete = ip.Completer.complete
922 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
923 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
923 _, matches = complete(line_buffer="d['")
924 _, matches = complete(line_buffer="d['")
924 nt.assert_in("hello", matches)
925 nt.assert_in("hello", matches)
925 nt.assert_in("world", matches)
926 nt.assert_in("world", matches)
926
927
927
928
928 def test_dict_key_completion_invalids():
929 def test_dict_key_completion_invalids():
929 """Smoke test cases dict key completion can't handle"""
930 """Smoke test cases dict key completion can't handle"""
930 ip = get_ipython()
931 ip = get_ipython()
931 complete = ip.Completer.complete
932 complete = ip.Completer.complete
932
933
933 ip.user_ns['no_getitem'] = None
934 ip.user_ns['no_getitem'] = None
934 ip.user_ns['no_keys'] = []
935 ip.user_ns['no_keys'] = []
935 ip.user_ns['cant_call_keys'] = dict
936 ip.user_ns['cant_call_keys'] = dict
936 ip.user_ns['empty'] = {}
937 ip.user_ns['empty'] = {}
937 ip.user_ns['d'] = {'abc': 5}
938 ip.user_ns['d'] = {'abc': 5}
938
939
939 _, matches = complete(line_buffer="no_getitem['")
940 _, matches = complete(line_buffer="no_getitem['")
940 _, matches = complete(line_buffer="no_keys['")
941 _, matches = complete(line_buffer="no_keys['")
941 _, matches = complete(line_buffer="cant_call_keys['")
942 _, matches = complete(line_buffer="cant_call_keys['")
942 _, matches = complete(line_buffer="empty['")
943 _, matches = complete(line_buffer="empty['")
943 _, matches = complete(line_buffer="name_error['")
944 _, matches = complete(line_buffer="name_error['")
944 _, matches = complete(line_buffer="d['\\") # incomplete escape
945 _, matches = complete(line_buffer="d['\\") # incomplete escape
945
946
946 class KeyCompletable(object):
947 class KeyCompletable(object):
947 def __init__(self, things=()):
948 def __init__(self, things=()):
948 self.things = things
949 self.things = things
949
950
950 def _ipython_key_completions_(self):
951 def _ipython_key_completions_(self):
951 return list(self.things)
952 return list(self.things)
952
953
953 def test_object_key_completion():
954 def test_object_key_completion():
954 ip = get_ipython()
955 ip = get_ipython()
955 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
956 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
956
957
957 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
958 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
958 nt.assert_in('qwerty', matches)
959 nt.assert_in('qwerty', matches)
959 nt.assert_in('qwick', matches)
960 nt.assert_in('qwick', matches)
960
961
961
962
962 class NamedInstanceMetaclass(type):
963 class NamedInstanceMetaclass(type):
963 def __getitem__(cls, item):
964 def __getitem__(cls, item):
964 return cls.get_instance(item)
965 return cls.get_instance(item)
965
966
966 class NamedInstanceClass(object, metaclass=NamedInstanceMetaclass):
967 class NamedInstanceClass(object, metaclass=NamedInstanceMetaclass):
967 def __init__(self, name):
968 def __init__(self, name):
968 if not hasattr(self.__class__, 'instances'):
969 if not hasattr(self.__class__, 'instances'):
969 self.__class__.instances = {}
970 self.__class__.instances = {}
970 self.__class__.instances[name] = self
971 self.__class__.instances[name] = self
971
972
972 @classmethod
973 @classmethod
973 def _ipython_key_completions_(cls):
974 def _ipython_key_completions_(cls):
974 return cls.instances.keys()
975 return cls.instances.keys()
975
976
976 @classmethod
977 @classmethod
977 def get_instance(cls, name):
978 def get_instance(cls, name):
978 return cls.instances[name]
979 return cls.instances[name]
979
980
980 def test_class_key_completion():
981 def test_class_key_completion():
981 ip = get_ipython()
982 ip = get_ipython()
982 NamedInstanceClass('qwerty')
983 NamedInstanceClass('qwerty')
983 NamedInstanceClass('qwick')
984 NamedInstanceClass('qwick')
984 ip.user_ns['named_instance_class'] = NamedInstanceClass
985 ip.user_ns['named_instance_class'] = NamedInstanceClass
985
986
986 _, matches = ip.Completer.complete(line_buffer="named_instance_class['qw")
987 _, matches = ip.Completer.complete(line_buffer="named_instance_class['qw")
987 nt.assert_in('qwerty', matches)
988 nt.assert_in('qwerty', matches)
988 nt.assert_in('qwick', matches)
989 nt.assert_in('qwick', matches)
989
990
990 def test_tryimport():
991 def test_tryimport():
991 """
992 """
992 Test that try-import don't crash on trailing dot, and import modules before
993 Test that try-import don't crash on trailing dot, and import modules before
993 """
994 """
994 from IPython.core.completerlib import try_import
995 from IPython.core.completerlib import try_import
995 assert(try_import("IPython."))
996 assert(try_import("IPython."))
996
997
997
998
998 def test_aimport_module_completer():
999 def test_aimport_module_completer():
999 ip = get_ipython()
1000 ip = get_ipython()
1000 _, matches = ip.complete('i', '%aimport i')
1001 _, matches = ip.complete('i', '%aimport i')
1001 nt.assert_in('io', matches)
1002 nt.assert_in('io', matches)
1002 nt.assert_not_in('int', matches)
1003 nt.assert_not_in('int', matches)
1003
1004
1004 def test_nested_import_module_completer():
1005 def test_nested_import_module_completer():
1005 ip = get_ipython()
1006 ip = get_ipython()
1006 _, matches = ip.complete(None, 'import IPython.co', 17)
1007 _, matches = ip.complete(None, 'import IPython.co', 17)
1007 nt.assert_in('IPython.core', matches)
1008 nt.assert_in('IPython.core', matches)
1008 nt.assert_not_in('import IPython.core', matches)
1009 nt.assert_not_in('import IPython.core', matches)
1009 nt.assert_not_in('IPython.display', matches)
1010 nt.assert_not_in('IPython.display', matches)
1010
1011
1011 def test_import_module_completer():
1012 def test_import_module_completer():
1012 ip = get_ipython()
1013 ip = get_ipython()
1013 _, matches = ip.complete('i', 'import i')
1014 _, matches = ip.complete('i', 'import i')
1014 nt.assert_in('io', matches)
1015 nt.assert_in('io', matches)
1015 nt.assert_not_in('int', matches)
1016 nt.assert_not_in('int', matches)
1016
1017
1017 def test_from_module_completer():
1018 def test_from_module_completer():
1018 ip = get_ipython()
1019 ip = get_ipython()
1019 _, matches = ip.complete('B', 'from io import B', 16)
1020 _, matches = ip.complete('B', 'from io import B', 16)
1020 nt.assert_in('BytesIO', matches)
1021 nt.assert_in('BytesIO', matches)
1021 nt.assert_not_in('BaseException', matches)
1022 nt.assert_not_in('BaseException', matches)
1022
1023
1023 def test_snake_case_completion():
1024 def test_snake_case_completion():
1024 ip = get_ipython()
1025 ip = get_ipython()
1025 ip.Completer.use_jedi = False
1026 ip.Completer.use_jedi = False
1026 ip.user_ns['some_three'] = 3
1027 ip.user_ns['some_three'] = 3
1027 ip.user_ns['some_four'] = 4
1028 ip.user_ns['some_four'] = 4
1028 _, matches = ip.complete("s_", "print(s_f")
1029 _, matches = ip.complete("s_", "print(s_f")
1029 nt.assert_in('some_three', matches)
1030 nt.assert_in('some_three', matches)
1030 nt.assert_in('some_four', matches)
1031 nt.assert_in('some_four', matches)
1031
1032
1032 def test_mix_terms():
1033 def test_mix_terms():
1033 ip = get_ipython()
1034 ip = get_ipython()
1034 from textwrap import dedent
1035 from textwrap import dedent
1035 ip.Completer.use_jedi = False
1036 ip.Completer.use_jedi = False
1036 ip.ex(dedent("""
1037 ip.ex(dedent("""
1037 class Test:
1038 class Test:
1038 def meth(self, meth_arg1):
1039 def meth(self, meth_arg1):
1039 print("meth")
1040 print("meth")
1040
1041
1041 def meth_1(self, meth1_arg1, meth1_arg2):
1042 def meth_1(self, meth1_arg1, meth1_arg2):
1042 print("meth1")
1043 print("meth1")
1043
1044
1044 def meth_2(self, meth2_arg1, meth2_arg2):
1045 def meth_2(self, meth2_arg1, meth2_arg2):
1045 print("meth2")
1046 print("meth2")
1046 test = Test()
1047 test = Test()
1047 """))
1048 """))
1048 _, matches = ip.complete(None, "test.meth(")
1049 _, matches = ip.complete(None, "test.meth(")
1049 nt.assert_in('meth_arg1=', matches)
1050 nt.assert_in('meth_arg1=', matches)
1050 nt.assert_not_in('meth2_arg1=', matches)
1051 nt.assert_not_in('meth2_arg1=', matches)
General Comments 0
You need to be logged in to leave comments. Login now