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