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