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