##// END OF EJS Templates
Prepare some test for pytest in completers....
Matthias Bussonnier -
Show More
@@ -1,1050 +1,1051 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 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 186 @decorators.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 237 @decorators.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 with greedy_completion(), provisionalcompleter():
391 def _(line, cursor_pos, expect, message, completion):
390 def _(line, cursor_pos, expect, message, completion):
391 with greedy_completion(), provisionalcompleter():
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 with provisionalcompleter():
401 402 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s", Completion(5,5, 'real')
402 403 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s", Completion(5,6, 'real')
403 404
404 405 if sys.version_info > (3, 4):
405 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 409 def test_omit__names():
409 410 # also happens to test IPCompleter as a configurable
410 411 ip = get_ipython()
411 412 ip._hidden_attr = 1
412 413 ip._x = {}
413 414 c = ip.Completer
414 415 ip.ex('ip=get_ipython()')
415 416 cfg = Config()
416 417 cfg.IPCompleter.omit__names = 0
417 418 c.update_config(cfg)
418 419 with provisionalcompleter():
419 420 c.use_jedi = False
420 421 s,matches = c.complete('ip.')
421 422 nt.assert_in('ip.__str__', matches)
422 423 nt.assert_in('ip._hidden_attr', matches)
423 424
424 425 # c.use_jedi = True
425 426 # completions = set(c.completions('ip.', 3))
426 427 # nt.assert_in(Completion(3, 3, '__str__'), completions)
427 428 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
428 429
429 430
430 431 cfg = Config()
431 432 cfg.IPCompleter.omit__names = 1
432 433 c.update_config(cfg)
433 434 with provisionalcompleter():
434 435 c.use_jedi = False
435 436 s,matches = c.complete('ip.')
436 437 nt.assert_not_in('ip.__str__', matches)
437 438 # nt.assert_in('ip._hidden_attr', matches)
438 439
439 440 # c.use_jedi = True
440 441 # completions = set(c.completions('ip.', 3))
441 442 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
442 443 # nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
443 444
444 445 cfg = Config()
445 446 cfg.IPCompleter.omit__names = 2
446 447 c.update_config(cfg)
447 448 with provisionalcompleter():
448 449 c.use_jedi = False
449 450 s,matches = c.complete('ip.')
450 451 nt.assert_not_in('ip.__str__', matches)
451 452 nt.assert_not_in('ip._hidden_attr', matches)
452 453
453 454 # c.use_jedi = True
454 455 # completions = set(c.completions('ip.', 3))
455 456 # nt.assert_not_in(Completion(3,3,'__str__'), completions)
456 457 # nt.assert_not_in(Completion(3,3, "_hidden_attr"), completions)
457 458
458 459 with provisionalcompleter():
459 460 c.use_jedi = False
460 461 s,matches = c.complete('ip._x.')
461 462 nt.assert_in('ip._x.keys', matches)
462 463
463 464 # c.use_jedi = True
464 465 # completions = set(c.completions('ip._x.', 6))
465 466 # nt.assert_in(Completion(6,6, "keys"), completions)
466 467
467 468 del ip._hidden_attr
468 469 del ip._x
469 470
470 471
471 472 def test_limit_to__all__False_ok():
472 473 """
473 474 Limit to all is deprecated, once we remove it this test can go away.
474 475 """
475 476 ip = get_ipython()
476 477 c = ip.Completer
477 478 c.use_jedi = False
478 479 ip.ex('class D: x=24')
479 480 ip.ex('d=D()')
480 481 cfg = Config()
481 482 cfg.IPCompleter.limit_to__all__ = False
482 483 c.update_config(cfg)
483 484 s, matches = c.complete('d.')
484 485 nt.assert_in('d.x', matches)
485 486
486 487
487 488 def test_get__all__entries_ok():
488 489 class A(object):
489 490 __all__ = ['x', 1]
490 491 words = completer.get__all__entries(A())
491 492 nt.assert_equal(words, ['x'])
492 493
493 494
494 495 def test_get__all__entries_no__all__ok():
495 496 class A(object):
496 497 pass
497 498 words = completer.get__all__entries(A())
498 499 nt.assert_equal(words, [])
499 500
500 501
501 502 def test_func_kw_completions():
502 503 ip = get_ipython()
503 504 c = ip.Completer
504 505 c.use_jedi = False
505 506 ip.ex('def myfunc(a=1,b=2): return a+b')
506 507 s, matches = c.complete(None, 'myfunc(1,b')
507 508 nt.assert_in('b=', matches)
508 509 # Simulate completing with cursor right after b (pos==10):
509 510 s, matches = c.complete(None, 'myfunc(1,b)', 10)
510 511 nt.assert_in('b=', matches)
511 512 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
512 513 nt.assert_in('b=', matches)
513 514 #builtin function
514 515 s, matches = c.complete(None, 'min(k, k')
515 516 nt.assert_in('key=', matches)
516 517
517 518
518 519 def test_default_arguments_from_docstring():
519 520 ip = get_ipython()
520 521 c = ip.Completer
521 522 kwd = c._default_arguments_from_docstring(
522 523 'min(iterable[, key=func]) -> value')
523 524 nt.assert_equal(kwd, ['key'])
524 525 #with cython type etc
525 526 kwd = c._default_arguments_from_docstring(
526 527 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
527 528 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
528 529 #white spaces
529 530 kwd = c._default_arguments_from_docstring(
530 531 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
531 532 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
532 533
533 534 def test_line_magics():
534 535 ip = get_ipython()
535 536 c = ip.Completer
536 537 s, matches = c.complete(None, 'lsmag')
537 538 nt.assert_in('%lsmagic', matches)
538 539 s, matches = c.complete(None, '%lsmag')
539 540 nt.assert_in('%lsmagic', matches)
540 541
541 542
542 543 def test_cell_magics():
543 544 from IPython.core.magic import register_cell_magic
544 545
545 546 @register_cell_magic
546 547 def _foo_cellm(line, cell):
547 548 pass
548 549
549 550 ip = get_ipython()
550 551 c = ip.Completer
551 552
552 553 s, matches = c.complete(None, '_foo_ce')
553 554 nt.assert_in('%%_foo_cellm', matches)
554 555 s, matches = c.complete(None, '%%_foo_ce')
555 556 nt.assert_in('%%_foo_cellm', matches)
556 557
557 558
558 559 def test_line_cell_magics():
559 560 from IPython.core.magic import register_line_cell_magic
560 561
561 562 @register_line_cell_magic
562 563 def _bar_cellm(line, cell):
563 564 pass
564 565
565 566 ip = get_ipython()
566 567 c = ip.Completer
567 568
568 569 # The policy here is trickier, see comments in completion code. The
569 570 # returned values depend on whether the user passes %% or not explicitly,
570 571 # and this will show a difference if the same name is both a line and cell
571 572 # magic.
572 573 s, matches = c.complete(None, '_bar_ce')
573 574 nt.assert_in('%_bar_cellm', matches)
574 575 nt.assert_in('%%_bar_cellm', matches)
575 576 s, matches = c.complete(None, '%_bar_ce')
576 577 nt.assert_in('%_bar_cellm', matches)
577 578 nt.assert_in('%%_bar_cellm', matches)
578 579 s, matches = c.complete(None, '%%_bar_ce')
579 580 nt.assert_not_in('%_bar_cellm', matches)
580 581 nt.assert_in('%%_bar_cellm', matches)
581 582
582 583
583 584 def test_magic_completion_order():
584 585 ip = get_ipython()
585 586 c = ip.Completer
586 587
587 588 # Test ordering of line and cell magics.
588 589 text, matches = c.complete("timeit")
589 590 nt.assert_equal(matches, ["%timeit", "%%timeit"])
590 591
591 592
592 593 def test_magic_completion_shadowing():
593 594 ip = get_ipython()
594 595 c = ip.Completer
595 596 c.use_jedi = False
596 597
597 598 # Before importing matplotlib, %matplotlib magic should be the only option.
598 599 text, matches = c.complete("mat")
599 600 nt.assert_equal(matches, ["%matplotlib"])
600 601
601 602 # The newly introduced name should shadow the magic.
602 603 ip.run_cell("matplotlib = 1")
603 604 text, matches = c.complete("mat")
604 605 nt.assert_equal(matches, ["matplotlib"])
605 606
606 607 # After removing matplotlib from namespace, the magic should again be
607 608 # the only option.
608 609 del ip.user_ns["matplotlib"]
609 610 text, matches = c.complete("mat")
610 611 nt.assert_equal(matches, ["%matplotlib"])
611 612
612 613 def test_magic_completion_shadowing_explicit():
613 614 """
614 615 If the user try to complete a shadowed magic, and explicit % start should
615 616 still return the completions.
616 617 """
617 618 ip = get_ipython()
618 619 c = ip.Completer
619 620
620 621 # Before importing matplotlib, %matplotlib magic should be the only option.
621 622 text, matches = c.complete("%mat")
622 623 nt.assert_equal(matches, ["%matplotlib"])
623 624
624 625 ip.run_cell("matplotlib = 1")
625 626
626 627 # After removing matplotlib from namespace, the magic should still be
627 628 # the only option.
628 629 text, matches = c.complete("%mat")
629 630 nt.assert_equal(matches, ["%matplotlib"])
630 631
631 632 def test_magic_config():
632 633 ip = get_ipython()
633 634 c = ip.Completer
634 635
635 636 s, matches = c.complete(None, 'conf')
636 637 nt.assert_in('%config', matches)
637 638 s, matches = c.complete(None, 'conf')
638 639 nt.assert_not_in('AliasManager', matches)
639 640 s, matches = c.complete(None, 'config ')
640 641 nt.assert_in('AliasManager', matches)
641 642 s, matches = c.complete(None, '%config ')
642 643 nt.assert_in('AliasManager', matches)
643 644 s, matches = c.complete(None, 'config Ali')
644 645 nt.assert_list_equal(['AliasManager'], matches)
645 646 s, matches = c.complete(None, '%config Ali')
646 647 nt.assert_list_equal(['AliasManager'], matches)
647 648 s, matches = c.complete(None, 'config AliasManager')
648 649 nt.assert_list_equal(['AliasManager'], matches)
649 650 s, matches = c.complete(None, '%config AliasManager')
650 651 nt.assert_list_equal(['AliasManager'], matches)
651 652 s, matches = c.complete(None, 'config AliasManager.')
652 653 nt.assert_in('AliasManager.default_aliases', matches)
653 654 s, matches = c.complete(None, '%config AliasManager.')
654 655 nt.assert_in('AliasManager.default_aliases', matches)
655 656 s, matches = c.complete(None, 'config AliasManager.de')
656 657 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
657 658 s, matches = c.complete(None, 'config AliasManager.de')
658 659 nt.assert_list_equal(['AliasManager.default_aliases'], matches)
659 660
660 661
661 662 def test_magic_color():
662 663 ip = get_ipython()
663 664 c = ip.Completer
664 665
665 666 s, matches = c.complete(None, 'colo')
666 667 nt.assert_in('%colors', matches)
667 668 s, matches = c.complete(None, 'colo')
668 669 nt.assert_not_in('NoColor', matches)
669 670 s, matches = c.complete(None, '%colors') # No trailing space
670 671 nt.assert_not_in('NoColor', matches)
671 672 s, matches = c.complete(None, 'colors ')
672 673 nt.assert_in('NoColor', matches)
673 674 s, matches = c.complete(None, '%colors ')
674 675 nt.assert_in('NoColor', matches)
675 676 s, matches = c.complete(None, 'colors NoCo')
676 677 nt.assert_list_equal(['NoColor'], matches)
677 678 s, matches = c.complete(None, '%colors NoCo')
678 679 nt.assert_list_equal(['NoColor'], matches)
679 680
680 681
681 682 def test_match_dict_keys():
682 683 """
683 684 Test that match_dict_keys works on a couple of use case does return what
684 685 expected, and does not crash
685 686 """
686 687 delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
687 688
688 689
689 690 keys = ['foo', b'far']
690 691 assert match_dict_keys(keys, "b'", delims=delims) == ("'", 2 ,['far'])
691 692 assert match_dict_keys(keys, "b'f", delims=delims) == ("'", 2 ,['far'])
692 693 assert match_dict_keys(keys, 'b"', delims=delims) == ('"', 2 ,['far'])
693 694 assert match_dict_keys(keys, 'b"f', delims=delims) == ('"', 2 ,['far'])
694 695
695 696 assert match_dict_keys(keys, "'", delims=delims) == ("'", 1 ,['foo'])
696 697 assert match_dict_keys(keys, "'f", delims=delims) == ("'", 1 ,['foo'])
697 698 assert match_dict_keys(keys, '"', delims=delims) == ('"', 1 ,['foo'])
698 699 assert match_dict_keys(keys, '"f', delims=delims) == ('"', 1 ,['foo'])
699 700
700 701 match_dict_keys
701 702
702 703
703 704 def test_dict_key_completion_string():
704 705 """Test dictionary key completion for string keys"""
705 706 ip = get_ipython()
706 707 complete = ip.Completer.complete
707 708
708 709 ip.user_ns['d'] = {'abc': None}
709 710
710 711 # check completion at different stages
711 712 _, matches = complete(line_buffer="d[")
712 713 nt.assert_in("'abc'", matches)
713 714 nt.assert_not_in("'abc']", matches)
714 715
715 716 _, matches = complete(line_buffer="d['")
716 717 nt.assert_in("abc", matches)
717 718 nt.assert_not_in("abc']", matches)
718 719
719 720 _, matches = complete(line_buffer="d['a")
720 721 nt.assert_in("abc", matches)
721 722 nt.assert_not_in("abc']", matches)
722 723
723 724 # check use of different quoting
724 725 _, matches = complete(line_buffer="d[\"")
725 726 nt.assert_in("abc", matches)
726 727 nt.assert_not_in('abc\"]', matches)
727 728
728 729 _, matches = complete(line_buffer="d[\"a")
729 730 nt.assert_in("abc", matches)
730 731 nt.assert_not_in('abc\"]', matches)
731 732
732 733 # check sensitivity to following context
733 734 _, matches = complete(line_buffer="d[]", cursor_pos=2)
734 735 nt.assert_in("'abc'", matches)
735 736
736 737 _, matches = complete(line_buffer="d['']", cursor_pos=3)
737 738 nt.assert_in("abc", matches)
738 739 nt.assert_not_in("abc'", matches)
739 740 nt.assert_not_in("abc']", matches)
740 741
741 742 # check multiple solutions are correctly returned and that noise is not
742 743 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
743 744 5: None}
744 745
745 746 _, matches = complete(line_buffer="d['a")
746 747 nt.assert_in("abc", matches)
747 748 nt.assert_in("abd", matches)
748 749 nt.assert_not_in("bad", matches)
749 750 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
750 751
751 752 # check escaping and whitespace
752 753 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
753 754 _, matches = complete(line_buffer="d['a")
754 755 nt.assert_in("a\\nb", matches)
755 756 nt.assert_in("a\\'b", matches)
756 757 nt.assert_in("a\"b", matches)
757 758 nt.assert_in("a word", matches)
758 759 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
759 760
760 761 # - can complete on non-initial word of the string
761 762 _, matches = complete(line_buffer="d['a w")
762 763 nt.assert_in("word", matches)
763 764
764 765 # - understands quote escaping
765 766 _, matches = complete(line_buffer="d['a\\'")
766 767 nt.assert_in("b", matches)
767 768
768 769 # - default quoting should work like repr
769 770 _, matches = complete(line_buffer="d[")
770 771 nt.assert_in("\"a'b\"", matches)
771 772
772 773 # - when opening quote with ", possible to match with unescaped apostrophe
773 774 _, matches = complete(line_buffer="d[\"a'")
774 775 nt.assert_in("b", matches)
775 776
776 777 # need to not split at delims that readline won't split at
777 778 if '-' not in ip.Completer.splitter.delims:
778 779 ip.user_ns['d'] = {'before-after': None}
779 780 _, matches = complete(line_buffer="d['before-af")
780 781 nt.assert_in('before-after', matches)
781 782
782 783 def test_dict_key_completion_contexts():
783 784 """Test expression contexts in which dict key completion occurs"""
784 785 ip = get_ipython()
785 786 complete = ip.Completer.complete
786 787 d = {'abc': None}
787 788 ip.user_ns['d'] = d
788 789
789 790 class C:
790 791 data = d
791 792 ip.user_ns['C'] = C
792 793 ip.user_ns['get'] = lambda: d
793 794
794 795 def assert_no_completion(**kwargs):
795 796 _, matches = complete(**kwargs)
796 797 nt.assert_not_in('abc', matches)
797 798 nt.assert_not_in('abc\'', matches)
798 799 nt.assert_not_in('abc\']', matches)
799 800 nt.assert_not_in('\'abc\'', matches)
800 801 nt.assert_not_in('\'abc\']', matches)
801 802
802 803 def assert_completion(**kwargs):
803 804 _, matches = complete(**kwargs)
804 805 nt.assert_in("'abc'", matches)
805 806 nt.assert_not_in("'abc']", matches)
806 807
807 808 # no completion after string closed, even if reopened
808 809 assert_no_completion(line_buffer="d['a'")
809 810 assert_no_completion(line_buffer="d[\"a\"")
810 811 assert_no_completion(line_buffer="d['a' + ")
811 812 assert_no_completion(line_buffer="d['a' + '")
812 813
813 814 # completion in non-trivial expressions
814 815 assert_completion(line_buffer="+ d[")
815 816 assert_completion(line_buffer="(d[")
816 817 assert_completion(line_buffer="C.data[")
817 818
818 819 # greedy flag
819 820 def assert_completion(**kwargs):
820 821 _, matches = complete(**kwargs)
821 822 nt.assert_in("get()['abc']", matches)
822 823
823 824 assert_no_completion(line_buffer="get()[")
824 825 with greedy_completion():
825 826 assert_completion(line_buffer="get()[")
826 827 assert_completion(line_buffer="get()['")
827 828 assert_completion(line_buffer="get()['a")
828 829 assert_completion(line_buffer="get()['ab")
829 830 assert_completion(line_buffer="get()['abc")
830 831
831 832
832 833
833 834 def test_dict_key_completion_bytes():
834 835 """Test handling of bytes in dict key completion"""
835 836 ip = get_ipython()
836 837 complete = ip.Completer.complete
837 838
838 839 ip.user_ns['d'] = {'abc': None, b'abd': None}
839 840
840 841 _, matches = complete(line_buffer="d[")
841 842 nt.assert_in("'abc'", matches)
842 843 nt.assert_in("b'abd'", matches)
843 844
844 845 if False: # not currently implemented
845 846 _, matches = complete(line_buffer="d[b")
846 847 nt.assert_in("b'abd'", matches)
847 848 nt.assert_not_in("b'abc'", matches)
848 849
849 850 _, matches = complete(line_buffer="d[b'")
850 851 nt.assert_in("abd", matches)
851 852 nt.assert_not_in("abc", matches)
852 853
853 854 _, matches = complete(line_buffer="d[B'")
854 855 nt.assert_in("abd", matches)
855 856 nt.assert_not_in("abc", matches)
856 857
857 858 _, matches = complete(line_buffer="d['")
858 859 nt.assert_in("abc", matches)
859 860 nt.assert_not_in("abd", matches)
860 861
861 862
862 863 def test_dict_key_completion_unicode_py3():
863 864 """Test handling of unicode in dict key completion"""
864 865 ip = get_ipython()
865 866 complete = ip.Completer.complete
866 867
867 868 ip.user_ns['d'] = {u'a\u05d0': None}
868 869
869 870 # query using escape
870 871 if sys.platform != 'win32':
871 872 # Known failure on Windows
872 873 _, matches = complete(line_buffer="d['a\\u05d0")
873 874 nt.assert_in("u05d0", matches) # tokenized after \\
874 875
875 876 # query using character
876 877 _, matches = complete(line_buffer="d['a\u05d0")
877 878 nt.assert_in(u"a\u05d0", matches)
878 879
879 880 with greedy_completion():
880 881 # query using escape
881 882 _, matches = complete(line_buffer="d['a\\u05d0")
882 883 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
883 884
884 885 # query using character
885 886 _, matches = complete(line_buffer="d['a\u05d0")
886 887 nt.assert_in(u"d['a\u05d0']", matches)
887 888
888 889
889 890
890 891 @dec.skip_without('numpy')
891 892 def test_struct_array_key_completion():
892 893 """Test dict key completion applies to numpy struct arrays"""
893 894 import numpy
894 895 ip = get_ipython()
895 896 complete = ip.Completer.complete
896 897 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
897 898 _, matches = complete(line_buffer="d['")
898 899 nt.assert_in("hello", matches)
899 900 nt.assert_in("world", matches)
900 901 # complete on the numpy struct itself
901 902 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
902 903 ('my_data', '>f4', 5)])
903 904 x = numpy.zeros(2, dtype=dt)
904 905 ip.user_ns['d'] = x[1]
905 906 _, matches = complete(line_buffer="d['")
906 907 nt.assert_in("my_head", matches)
907 908 nt.assert_in("my_data", matches)
908 909 # complete on a nested level
909 910 with greedy_completion():
910 911 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
911 912 _, matches = complete(line_buffer="d[1]['my_head']['")
912 913 nt.assert_true(any(["my_dt" in m for m in matches]))
913 914 nt.assert_true(any(["my_df" in m for m in matches]))
914 915
915 916
916 917 @dec.skip_without('pandas')
917 918 def test_dataframe_key_completion():
918 919 """Test dict key completion applies to pandas DataFrames"""
919 920 import pandas
920 921 ip = get_ipython()
921 922 complete = ip.Completer.complete
922 923 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
923 924 _, matches = complete(line_buffer="d['")
924 925 nt.assert_in("hello", matches)
925 926 nt.assert_in("world", matches)
926 927
927 928
928 929 def test_dict_key_completion_invalids():
929 930 """Smoke test cases dict key completion can't handle"""
930 931 ip = get_ipython()
931 932 complete = ip.Completer.complete
932 933
933 934 ip.user_ns['no_getitem'] = None
934 935 ip.user_ns['no_keys'] = []
935 936 ip.user_ns['cant_call_keys'] = dict
936 937 ip.user_ns['empty'] = {}
937 938 ip.user_ns['d'] = {'abc': 5}
938 939
939 940 _, matches = complete(line_buffer="no_getitem['")
940 941 _, matches = complete(line_buffer="no_keys['")
941 942 _, matches = complete(line_buffer="cant_call_keys['")
942 943 _, matches = complete(line_buffer="empty['")
943 944 _, matches = complete(line_buffer="name_error['")
944 945 _, matches = complete(line_buffer="d['\\") # incomplete escape
945 946
946 947 class KeyCompletable(object):
947 948 def __init__(self, things=()):
948 949 self.things = things
949 950
950 951 def _ipython_key_completions_(self):
951 952 return list(self.things)
952 953
953 954 def test_object_key_completion():
954 955 ip = get_ipython()
955 956 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
956 957
957 958 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
958 959 nt.assert_in('qwerty', matches)
959 960 nt.assert_in('qwick', matches)
960 961
961 962
962 963 class NamedInstanceMetaclass(type):
963 964 def __getitem__(cls, item):
964 965 return cls.get_instance(item)
965 966
966 967 class NamedInstanceClass(object, metaclass=NamedInstanceMetaclass):
967 968 def __init__(self, name):
968 969 if not hasattr(self.__class__, 'instances'):
969 970 self.__class__.instances = {}
970 971 self.__class__.instances[name] = self
971 972
972 973 @classmethod
973 974 def _ipython_key_completions_(cls):
974 975 return cls.instances.keys()
975 976
976 977 @classmethod
977 978 def get_instance(cls, name):
978 979 return cls.instances[name]
979 980
980 981 def test_class_key_completion():
981 982 ip = get_ipython()
982 983 NamedInstanceClass('qwerty')
983 984 NamedInstanceClass('qwick')
984 985 ip.user_ns['named_instance_class'] = NamedInstanceClass
985 986
986 987 _, matches = ip.Completer.complete(line_buffer="named_instance_class['qw")
987 988 nt.assert_in('qwerty', matches)
988 989 nt.assert_in('qwick', matches)
989 990
990 991 def test_tryimport():
991 992 """
992 993 Test that try-import don't crash on trailing dot, and import modules before
993 994 """
994 995 from IPython.core.completerlib import try_import
995 996 assert(try_import("IPython."))
996 997
997 998
998 999 def test_aimport_module_completer():
999 1000 ip = get_ipython()
1000 1001 _, matches = ip.complete('i', '%aimport i')
1001 1002 nt.assert_in('io', matches)
1002 1003 nt.assert_not_in('int', matches)
1003 1004
1004 1005 def test_nested_import_module_completer():
1005 1006 ip = get_ipython()
1006 1007 _, matches = ip.complete(None, 'import IPython.co', 17)
1007 1008 nt.assert_in('IPython.core', matches)
1008 1009 nt.assert_not_in('import IPython.core', matches)
1009 1010 nt.assert_not_in('IPython.display', matches)
1010 1011
1011 1012 def test_import_module_completer():
1012 1013 ip = get_ipython()
1013 1014 _, matches = ip.complete('i', 'import i')
1014 1015 nt.assert_in('io', matches)
1015 1016 nt.assert_not_in('int', matches)
1016 1017
1017 1018 def test_from_module_completer():
1018 1019 ip = get_ipython()
1019 1020 _, matches = ip.complete('B', 'from io import B', 16)
1020 1021 nt.assert_in('BytesIO', matches)
1021 1022 nt.assert_not_in('BaseException', matches)
1022 1023
1023 1024 def test_snake_case_completion():
1024 1025 ip = get_ipython()
1025 1026 ip.Completer.use_jedi = False
1026 1027 ip.user_ns['some_three'] = 3
1027 1028 ip.user_ns['some_four'] = 4
1028 1029 _, matches = ip.complete("s_", "print(s_f")
1029 1030 nt.assert_in('some_three', matches)
1030 1031 nt.assert_in('some_four', matches)
1031 1032
1032 1033 def test_mix_terms():
1033 1034 ip = get_ipython()
1034 1035 from textwrap import dedent
1035 1036 ip.Completer.use_jedi = False
1036 1037 ip.ex(dedent("""
1037 1038 class Test:
1038 1039 def meth(self, meth_arg1):
1039 1040 print("meth")
1040 1041
1041 1042 def meth_1(self, meth1_arg1, meth1_arg2):
1042 1043 print("meth1")
1043 1044
1044 1045 def meth_2(self, meth2_arg1, meth2_arg2):
1045 1046 print("meth2")
1046 1047 test = Test()
1047 1048 """))
1048 1049 _, matches = ip.complete(None, "test.meth(")
1049 1050 nt.assert_in('meth_arg1=', matches)
1050 1051 nt.assert_not_in('meth2_arg1=', matches)
General Comments 0
You need to be logged in to leave comments. Login now