##// END OF EJS Templates
Merge pull request #8339 from takluyver/ascii-completions-test-cwd...
Matthias Bussonnier -
r21283:8a631498 merge
parent child Browse files
Show More
@@ -1,754 +1,755 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.core import completer
17 17 from IPython.external.decorators import knownfailureif
18 18 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 19 from IPython.utils.generics import complete_object
20 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 with TemporaryWorkingDirectory(): # Avoid any filename completions
182 183 # single ascii letter that don't have yet completions
183 184 for letter in 'fjqyJMQVWY' :
184 185 name, matches = ip.complete('\\'+letter)
185 nt.assert_equal(len(matches), 0)
186 nt.assert_equal(matches, [])
186 187
187 188
188 189
189 190
190 191 class CompletionSplitterTestCase(unittest.TestCase):
191 192 def setUp(self):
192 193 self.sp = completer.CompletionSplitter()
193 194
194 195 def test_delim_setting(self):
195 196 self.sp.delims = ' '
196 197 nt.assert_equal(self.sp.delims, ' ')
197 198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
198 199
199 200 def test_spaces(self):
200 201 """Test with only spaces as split chars."""
201 202 self.sp.delims = ' '
202 203 t = [('foo', '', 'foo'),
203 204 ('run foo', '', 'foo'),
204 205 ('run foo', 'bar', 'foo'),
205 206 ]
206 207 check_line_split(self.sp, t)
207 208
208 209
209 210 def test_has_open_quotes1():
210 211 for s in ["'", "'''", "'hi' '"]:
211 212 nt.assert_equal(completer.has_open_quotes(s), "'")
212 213
213 214
214 215 def test_has_open_quotes2():
215 216 for s in ['"', '"""', '"hi" "']:
216 217 nt.assert_equal(completer.has_open_quotes(s), '"')
217 218
218 219
219 220 def test_has_open_quotes3():
220 221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
221 222 nt.assert_false(completer.has_open_quotes(s))
222 223
223 224
224 225 def test_has_open_quotes4():
225 226 for s in ['""', '""" """', '"hi" "ipython"']:
226 227 nt.assert_false(completer.has_open_quotes(s))
227 228
228 229
229 230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
230 231 def test_abspath_file_completions():
231 232 ip = get_ipython()
232 233 with TemporaryDirectory() as tmpdir:
233 234 prefix = os.path.join(tmpdir, 'foo')
234 235 suffixes = ['1', '2']
235 236 names = [prefix+s for s in suffixes]
236 237 for n in names:
237 238 open(n, 'w').close()
238 239
239 240 # Check simple completion
240 241 c = ip.complete(prefix)[1]
241 242 nt.assert_equal(c, names)
242 243
243 244 # Now check with a function call
244 245 cmd = 'a = f("%s' % prefix
245 246 c = ip.complete(prefix, cmd)[1]
246 247 comp = [prefix+s for s in suffixes]
247 248 nt.assert_equal(c, comp)
248 249
249 250
250 251 def test_local_file_completions():
251 252 ip = get_ipython()
252 253 with TemporaryWorkingDirectory():
253 254 prefix = './foo'
254 255 suffixes = ['1', '2']
255 256 names = [prefix+s for s in suffixes]
256 257 for n in names:
257 258 open(n, 'w').close()
258 259
259 260 # Check simple completion
260 261 c = ip.complete(prefix)[1]
261 262 nt.assert_equal(c, names)
262 263
263 264 # Now check with a function call
264 265 cmd = 'a = f("%s' % prefix
265 266 c = ip.complete(prefix, cmd)[1]
266 267 comp = [prefix+s for s in suffixes]
267 268 nt.assert_equal(c, comp)
268 269
269 270
270 271 def test_greedy_completions():
271 272 ip = get_ipython()
272 273 ip.ex('a=list(range(5))')
273 274 _,c = ip.complete('.',line='a[0].')
274 275 nt.assert_false('a[0].real' in c,
275 276 "Shouldn't have completed on a[0]: %s"%c)
276 277 with greedy_completion():
277 278 _,c = ip.complete('.',line='a[0].')
278 279 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
279 280
280 281
281 282 def test_omit__names():
282 283 # also happens to test IPCompleter as a configurable
283 284 ip = get_ipython()
284 285 ip._hidden_attr = 1
285 286 ip._x = {}
286 287 c = ip.Completer
287 288 ip.ex('ip=get_ipython()')
288 289 cfg = Config()
289 290 cfg.IPCompleter.omit__names = 0
290 291 c.update_config(cfg)
291 292 s,matches = c.complete('ip.')
292 293 nt.assert_in('ip.__str__', matches)
293 294 nt.assert_in('ip._hidden_attr', matches)
294 295 cfg.IPCompleter.omit__names = 1
295 296 c.update_config(cfg)
296 297 s,matches = c.complete('ip.')
297 298 nt.assert_not_in('ip.__str__', matches)
298 299 nt.assert_in('ip._hidden_attr', matches)
299 300 cfg.IPCompleter.omit__names = 2
300 301 c.update_config(cfg)
301 302 s,matches = c.complete('ip.')
302 303 nt.assert_not_in('ip.__str__', matches)
303 304 nt.assert_not_in('ip._hidden_attr', matches)
304 305 s,matches = c.complete('ip._x.')
305 306 nt.assert_in('ip._x.keys', matches)
306 307 del ip._hidden_attr
307 308
308 309
309 310 def test_limit_to__all__False_ok():
310 311 ip = get_ipython()
311 312 c = ip.Completer
312 313 ip.ex('class D: x=24')
313 314 ip.ex('d=D()')
314 315 cfg = Config()
315 316 cfg.IPCompleter.limit_to__all__ = False
316 317 c.update_config(cfg)
317 318 s, matches = c.complete('d.')
318 319 nt.assert_in('d.x', matches)
319 320
320 321
321 322 def test_limit_to__all__True_ok():
322 323 ip = get_ipython()
323 324 c = ip.Completer
324 325 ip.ex('class D: x=24')
325 326 ip.ex('d=D()')
326 327 ip.ex("d.__all__=['z']")
327 328 cfg = Config()
328 329 cfg.IPCompleter.limit_to__all__ = True
329 330 c.update_config(cfg)
330 331 s, matches = c.complete('d.')
331 332 nt.assert_in('d.z', matches)
332 333 nt.assert_not_in('d.x', matches)
333 334
334 335
335 336 def test_get__all__entries_ok():
336 337 class A(object):
337 338 __all__ = ['x', 1]
338 339 words = completer.get__all__entries(A())
339 340 nt.assert_equal(words, ['x'])
340 341
341 342
342 343 def test_get__all__entries_no__all__ok():
343 344 class A(object):
344 345 pass
345 346 words = completer.get__all__entries(A())
346 347 nt.assert_equal(words, [])
347 348
348 349
349 350 def test_func_kw_completions():
350 351 ip = get_ipython()
351 352 c = ip.Completer
352 353 ip.ex('def myfunc(a=1,b=2): return a+b')
353 354 s, matches = c.complete(None, 'myfunc(1,b')
354 355 nt.assert_in('b=', matches)
355 356 # Simulate completing with cursor right after b (pos==10):
356 357 s, matches = c.complete(None, 'myfunc(1,b)', 10)
357 358 nt.assert_in('b=', matches)
358 359 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
359 360 nt.assert_in('b=', matches)
360 361 #builtin function
361 362 s, matches = c.complete(None, 'min(k, k')
362 363 nt.assert_in('key=', matches)
363 364
364 365
365 366 def test_default_arguments_from_docstring():
366 367 doc = min.__doc__
367 368 ip = get_ipython()
368 369 c = ip.Completer
369 370 kwd = c._default_arguments_from_docstring(
370 371 'min(iterable[, key=func]) -> value')
371 372 nt.assert_equal(kwd, ['key'])
372 373 #with cython type etc
373 374 kwd = c._default_arguments_from_docstring(
374 375 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
375 376 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
376 377 #white spaces
377 378 kwd = c._default_arguments_from_docstring(
378 379 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
379 380 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
380 381
381 382 def test_line_magics():
382 383 ip = get_ipython()
383 384 c = ip.Completer
384 385 s, matches = c.complete(None, 'lsmag')
385 386 nt.assert_in('%lsmagic', matches)
386 387 s, matches = c.complete(None, '%lsmag')
387 388 nt.assert_in('%lsmagic', matches)
388 389
389 390
390 391 def test_cell_magics():
391 392 from IPython.core.magic import register_cell_magic
392 393
393 394 @register_cell_magic
394 395 def _foo_cellm(line, cell):
395 396 pass
396 397
397 398 ip = get_ipython()
398 399 c = ip.Completer
399 400
400 401 s, matches = c.complete(None, '_foo_ce')
401 402 nt.assert_in('%%_foo_cellm', matches)
402 403 s, matches = c.complete(None, '%%_foo_ce')
403 404 nt.assert_in('%%_foo_cellm', matches)
404 405
405 406
406 407 def test_line_cell_magics():
407 408 from IPython.core.magic import register_line_cell_magic
408 409
409 410 @register_line_cell_magic
410 411 def _bar_cellm(line, cell):
411 412 pass
412 413
413 414 ip = get_ipython()
414 415 c = ip.Completer
415 416
416 417 # The policy here is trickier, see comments in completion code. The
417 418 # returned values depend on whether the user passes %% or not explicitly,
418 419 # and this will show a difference if the same name is both a line and cell
419 420 # magic.
420 421 s, matches = c.complete(None, '_bar_ce')
421 422 nt.assert_in('%_bar_cellm', matches)
422 423 nt.assert_in('%%_bar_cellm', matches)
423 424 s, matches = c.complete(None, '%_bar_ce')
424 425 nt.assert_in('%_bar_cellm', matches)
425 426 nt.assert_in('%%_bar_cellm', matches)
426 427 s, matches = c.complete(None, '%%_bar_ce')
427 428 nt.assert_not_in('%_bar_cellm', matches)
428 429 nt.assert_in('%%_bar_cellm', matches)
429 430
430 431
431 432 def test_magic_completion_order():
432 433
433 434 ip = get_ipython()
434 435 c = ip.Completer
435 436
436 437 # Test ordering of magics and non-magics with the same name
437 438 # We want the non-magic first
438 439
439 440 # Before importing matplotlib, there should only be one option:
440 441
441 442 text, matches = c.complete('mat')
442 443 nt.assert_equal(matches, ["%matplotlib"])
443 444
444 445
445 446 ip.run_cell("matplotlib = 1") # introduce name into namespace
446 447
447 448 # After the import, there should be two options, ordered like this:
448 449 text, matches = c.complete('mat')
449 450 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
450 451
451 452
452 453 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
453 454
454 455 # Order of user variable and line and cell magics with same name:
455 456 text, matches = c.complete('timeit')
456 457 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
457 458
458 459
459 460 def test_dict_key_completion_string():
460 461 """Test dictionary key completion for string keys"""
461 462 ip = get_ipython()
462 463 complete = ip.Completer.complete
463 464
464 465 ip.user_ns['d'] = {'abc': None}
465 466
466 467 # check completion at different stages
467 468 _, matches = complete(line_buffer="d[")
468 469 nt.assert_in("'abc'", matches)
469 470 nt.assert_not_in("'abc']", matches)
470 471
471 472 _, matches = complete(line_buffer="d['")
472 473 nt.assert_in("abc", matches)
473 474 nt.assert_not_in("abc']", matches)
474 475
475 476 _, matches = complete(line_buffer="d['a")
476 477 nt.assert_in("abc", matches)
477 478 nt.assert_not_in("abc']", matches)
478 479
479 480 # check use of different quoting
480 481 _, matches = complete(line_buffer="d[\"")
481 482 nt.assert_in("abc", matches)
482 483 nt.assert_not_in('abc\"]', matches)
483 484
484 485 _, matches = complete(line_buffer="d[\"a")
485 486 nt.assert_in("abc", matches)
486 487 nt.assert_not_in('abc\"]', matches)
487 488
488 489 # check sensitivity to following context
489 490 _, matches = complete(line_buffer="d[]", cursor_pos=2)
490 491 nt.assert_in("'abc'", matches)
491 492
492 493 _, matches = complete(line_buffer="d['']", cursor_pos=3)
493 494 nt.assert_in("abc", matches)
494 495 nt.assert_not_in("abc'", matches)
495 496 nt.assert_not_in("abc']", matches)
496 497
497 498 # check multiple solutions are correctly returned and that noise is not
498 499 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
499 500 5: None}
500 501
501 502 _, matches = complete(line_buffer="d['a")
502 503 nt.assert_in("abc", matches)
503 504 nt.assert_in("abd", matches)
504 505 nt.assert_not_in("bad", matches)
505 506 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
506 507
507 508 # check escaping and whitespace
508 509 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
509 510 _, matches = complete(line_buffer="d['a")
510 511 nt.assert_in("a\\nb", matches)
511 512 nt.assert_in("a\\'b", matches)
512 513 nt.assert_in("a\"b", matches)
513 514 nt.assert_in("a word", matches)
514 515 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
515 516
516 517 # - can complete on non-initial word of the string
517 518 _, matches = complete(line_buffer="d['a w")
518 519 nt.assert_in("word", matches)
519 520
520 521 # - understands quote escaping
521 522 _, matches = complete(line_buffer="d['a\\'")
522 523 nt.assert_in("b", matches)
523 524
524 525 # - default quoting should work like repr
525 526 _, matches = complete(line_buffer="d[")
526 527 nt.assert_in("\"a'b\"", matches)
527 528
528 529 # - when opening quote with ", possible to match with unescaped apostrophe
529 530 _, matches = complete(line_buffer="d[\"a'")
530 531 nt.assert_in("b", matches)
531 532
532 533
533 534 def test_dict_key_completion_contexts():
534 535 """Test expression contexts in which dict key completion occurs"""
535 536 ip = get_ipython()
536 537 complete = ip.Completer.complete
537 538 d = {'abc': None}
538 539 ip.user_ns['d'] = d
539 540
540 541 class C:
541 542 data = d
542 543 ip.user_ns['C'] = C
543 544 ip.user_ns['get'] = lambda: d
544 545
545 546 def assert_no_completion(**kwargs):
546 547 _, matches = complete(**kwargs)
547 548 nt.assert_not_in('abc', matches)
548 549 nt.assert_not_in('abc\'', matches)
549 550 nt.assert_not_in('abc\']', matches)
550 551 nt.assert_not_in('\'abc\'', matches)
551 552 nt.assert_not_in('\'abc\']', matches)
552 553
553 554 def assert_completion(**kwargs):
554 555 _, matches = complete(**kwargs)
555 556 nt.assert_in("'abc'", matches)
556 557 nt.assert_not_in("'abc']", matches)
557 558
558 559 # no completion after string closed, even if reopened
559 560 assert_no_completion(line_buffer="d['a'")
560 561 assert_no_completion(line_buffer="d[\"a\"")
561 562 assert_no_completion(line_buffer="d['a' + ")
562 563 assert_no_completion(line_buffer="d['a' + '")
563 564
564 565 # completion in non-trivial expressions
565 566 assert_completion(line_buffer="+ d[")
566 567 assert_completion(line_buffer="(d[")
567 568 assert_completion(line_buffer="C.data[")
568 569
569 570 # greedy flag
570 571 def assert_completion(**kwargs):
571 572 _, matches = complete(**kwargs)
572 573 nt.assert_in("get()['abc']", matches)
573 574
574 575 assert_no_completion(line_buffer="get()[")
575 576 with greedy_completion():
576 577 assert_completion(line_buffer="get()[")
577 578 assert_completion(line_buffer="get()['")
578 579 assert_completion(line_buffer="get()['a")
579 580 assert_completion(line_buffer="get()['ab")
580 581 assert_completion(line_buffer="get()['abc")
581 582
582 583
583 584
584 585 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
585 586 def test_dict_key_completion_bytes():
586 587 """Test handling of bytes in dict key completion"""
587 588 ip = get_ipython()
588 589 complete = ip.Completer.complete
589 590
590 591 ip.user_ns['d'] = {'abc': None, b'abd': None}
591 592
592 593 _, matches = complete(line_buffer="d[")
593 594 nt.assert_in("'abc'", matches)
594 595 nt.assert_in("b'abd'", matches)
595 596
596 597 if False: # not currently implemented
597 598 _, matches = complete(line_buffer="d[b")
598 599 nt.assert_in("b'abd'", matches)
599 600 nt.assert_not_in("b'abc'", matches)
600 601
601 602 _, matches = complete(line_buffer="d[b'")
602 603 nt.assert_in("abd", matches)
603 604 nt.assert_not_in("abc", matches)
604 605
605 606 _, matches = complete(line_buffer="d[B'")
606 607 nt.assert_in("abd", matches)
607 608 nt.assert_not_in("abc", matches)
608 609
609 610 _, matches = complete(line_buffer="d['")
610 611 nt.assert_in("abc", matches)
611 612 nt.assert_not_in("abd", matches)
612 613
613 614
614 615 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
615 616 def test_dict_key_completion_unicode_py2():
616 617 """Test handling of unicode in dict key completion"""
617 618 ip = get_ipython()
618 619 complete = ip.Completer.complete
619 620
620 621 ip.user_ns['d'] = {u'abc': None,
621 622 u'a\u05d0b': None}
622 623
623 624 _, matches = complete(line_buffer="d[")
624 625 nt.assert_in("u'abc'", matches)
625 626 nt.assert_in("u'a\\u05d0b'", matches)
626 627
627 628 _, matches = complete(line_buffer="d['a")
628 629 nt.assert_in("abc", matches)
629 630 nt.assert_not_in("a\\u05d0b", matches)
630 631
631 632 _, matches = complete(line_buffer="d[u'a")
632 633 nt.assert_in("abc", matches)
633 634 nt.assert_in("a\\u05d0b", matches)
634 635
635 636 _, matches = complete(line_buffer="d[U'a")
636 637 nt.assert_in("abc", matches)
637 638 nt.assert_in("a\\u05d0b", matches)
638 639
639 640 # query using escape
640 641 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
641 642 nt.assert_in("u05d0b", matches) # tokenized after \\
642 643
643 644 # query using character
644 645 _, matches = complete(line_buffer=u"d[u'a\u05d0")
645 646 nt.assert_in(u"a\u05d0b", matches)
646 647
647 648 with greedy_completion():
648 649 _, matches = complete(line_buffer="d[")
649 650 nt.assert_in("d[u'abc']", matches)
650 651 nt.assert_in("d[u'a\\u05d0b']", matches)
651 652
652 653 _, matches = complete(line_buffer="d['a")
653 654 nt.assert_in("d['abc']", matches)
654 655 nt.assert_not_in("d[u'a\\u05d0b']", matches)
655 656
656 657 _, matches = complete(line_buffer="d[u'a")
657 658 nt.assert_in("d[u'abc']", matches)
658 659 nt.assert_in("d[u'a\\u05d0b']", matches)
659 660
660 661 _, matches = complete(line_buffer="d[U'a")
661 662 nt.assert_in("d[U'abc']", matches)
662 663 nt.assert_in("d[U'a\\u05d0b']", matches)
663 664
664 665 # query using escape
665 666 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
666 667 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
667 668
668 669 # query using character
669 670 _, matches = complete(line_buffer=u"d[u'a\u05d0")
670 671 nt.assert_in(u"d[u'a\u05d0b']", matches)
671 672
672 673
673 674 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
674 675 def test_dict_key_completion_unicode_py3():
675 676 """Test handling of unicode in dict key completion"""
676 677 ip = get_ipython()
677 678 complete = ip.Completer.complete
678 679
679 680 ip.user_ns['d'] = {u'a\u05d0': None}
680 681
681 682 # query using escape
682 683 _, matches = complete(line_buffer="d['a\\u05d0")
683 684 nt.assert_in("u05d0", matches) # tokenized after \\
684 685
685 686 # query using character
686 687 _, matches = complete(line_buffer="d['a\u05d0")
687 688 nt.assert_in(u"a\u05d0", matches)
688 689
689 690 with greedy_completion():
690 691 # query using escape
691 692 _, matches = complete(line_buffer="d['a\\u05d0")
692 693 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
693 694
694 695 # query using character
695 696 _, matches = complete(line_buffer="d['a\u05d0")
696 697 nt.assert_in(u"d['a\u05d0']", matches)
697 698
698 699
699 700
700 701 @dec.skip_without('numpy')
701 702 def test_struct_array_key_completion():
702 703 """Test dict key completion applies to numpy struct arrays"""
703 704 import numpy
704 705 ip = get_ipython()
705 706 complete = ip.Completer.complete
706 707 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
707 708 _, matches = complete(line_buffer="d['")
708 709 nt.assert_in("hello", matches)
709 710 nt.assert_in("world", matches)
710 711 # complete on the numpy struct itself
711 712 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
712 713 ('my_data', '>f4', 5)])
713 714 x = numpy.zeros(2, dtype=dt)
714 715 ip.user_ns['d'] = x[1]
715 716 _, matches = complete(line_buffer="d['")
716 717 nt.assert_in("my_head", matches)
717 718 nt.assert_in("my_data", matches)
718 719 # complete on a nested level
719 720 with greedy_completion():
720 721 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
721 722 _, matches = complete(line_buffer="d[1]['my_head']['")
722 723 nt.assert_true(any(["my_dt" in m for m in matches]))
723 724 nt.assert_true(any(["my_df" in m for m in matches]))
724 725
725 726
726 727 @dec.skip_without('pandas')
727 728 def test_dataframe_key_completion():
728 729 """Test dict key completion applies to pandas DataFrames"""
729 730 import pandas
730 731 ip = get_ipython()
731 732 complete = ip.Completer.complete
732 733 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
733 734 _, matches = complete(line_buffer="d['")
734 735 nt.assert_in("hello", matches)
735 736 nt.assert_in("world", matches)
736 737
737 738
738 739 def test_dict_key_completion_invalids():
739 740 """Smoke test cases dict key completion can't handle"""
740 741 ip = get_ipython()
741 742 complete = ip.Completer.complete
742 743
743 744 ip.user_ns['no_getitem'] = None
744 745 ip.user_ns['no_keys'] = []
745 746 ip.user_ns['cant_call_keys'] = dict
746 747 ip.user_ns['empty'] = {}
747 748 ip.user_ns['d'] = {'abc': 5}
748 749
749 750 _, matches = complete(line_buffer="no_getitem['")
750 751 _, matches = complete(line_buffer="no_keys['")
751 752 _, matches = complete(line_buffer="cant_call_keys['")
752 753 _, matches = complete(line_buffer="empty['")
753 754 _, matches = complete(line_buffer="name_error['")
754 755 _, matches = complete(line_buffer="d['\\") # incomplete escape
General Comments 0
You need to be logged in to leave comments. Login now