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