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