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