##// END OF EJS Templates
Remove parso xfail for Python>=3.11...
Nikita Kniazev -
Show More
@@ -1,1280 +1,1275 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 pytest
9 9 import sys
10 10 import textwrap
11 11 import unittest
12 12
13 13 from contextlib import contextmanager
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.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 19 from IPython.utils.generics import complete_object
20 20 from IPython.testing import decorators as dec
21 21
22 22 from IPython.core.completer import (
23 23 Completion,
24 24 provisionalcompleter,
25 25 match_dict_keys,
26 26 _deduplicate_completions,
27 27 )
28 28
29 29 if sys.version_info >= (3, 10):
30 30 import jedi
31 31 from pkg_resources import parse_version
32 32
33 33 # Requires https://github.com/davidhalter/jedi/pull/1795
34 34 jedi_issue = parse_version(jedi.__version__) <= parse_version("0.18.0")
35 35 else:
36 36 jedi_issue = False
37 37
38 38 # -----------------------------------------------------------------------------
39 39 # Test functions
40 40 # -----------------------------------------------------------------------------
41 41
42 42 def recompute_unicode_ranges():
43 43 """
44 44 utility to recompute the largest unicode range without any characters
45 45
46 46 use to recompute the gap in the global _UNICODE_RANGES of completer.py
47 47 """
48 48 import itertools
49 49 import unicodedata
50 50 valid = []
51 51 for c in range(0,0x10FFFF + 1):
52 52 try:
53 53 unicodedata.name(chr(c))
54 54 except ValueError:
55 55 continue
56 56 valid.append(c)
57 57
58 58 def ranges(i):
59 59 for a, b in itertools.groupby(enumerate(i), lambda pair: pair[1] - pair[0]):
60 60 b = list(b)
61 61 yield b[0][1], b[-1][1]
62 62
63 63 rg = list(ranges(valid))
64 64 lens = []
65 65 gap_lens = []
66 66 pstart, pstop = 0,0
67 67 for start, stop in rg:
68 68 lens.append(stop-start)
69 69 gap_lens.append((start - pstop, hex(pstop), hex(start), f'{round((start - pstop)/0xe01f0*100)}%'))
70 70 pstart, pstop = start, stop
71 71
72 72 return sorted(gap_lens)[-1]
73 73
74 74
75 75
76 76 def test_unicode_range():
77 77 """
78 78 Test that the ranges we test for unicode names give the same number of
79 79 results than testing the full length.
80 80 """
81 81 from IPython.core.completer import _unicode_name_compute, _UNICODE_RANGES
82 82
83 83 expected_list = _unicode_name_compute([(0, 0x110000)])
84 84 test = _unicode_name_compute(_UNICODE_RANGES)
85 85 len_exp = len(expected_list)
86 86 len_test = len(test)
87 87
88 88 # do not inline the len() or on error pytest will try to print the 130 000 +
89 89 # elements.
90 90 message = None
91 91 if len_exp != len_test or len_exp > 131808:
92 92 size, start, stop, prct = recompute_unicode_ranges()
93 93 message = f"""_UNICODE_RANGES likely wrong and need updating. This is
94 94 likely due to a new release of Python. We've find that the biggest gap
95 95 in unicode characters has reduces in size to be {size} characters
96 96 ({prct}), from {start}, to {stop}. In completer.py likely update to
97 97
98 98 _UNICODE_RANGES = [(32, {start}), ({stop}, 0xe01f0)]
99 99
100 100 And update the assertion below to use
101 101
102 102 len_exp <= {len_exp}
103 103 """
104 104 assert len_exp == len_test, message
105 105
106 106 # fail if new unicode symbols have been added.
107 107 assert len_exp <= 138552, message
108 108
109 109
110 110 @contextmanager
111 111 def greedy_completion():
112 112 ip = get_ipython()
113 113 greedy_original = ip.Completer.greedy
114 114 try:
115 115 ip.Completer.greedy = True
116 116 yield
117 117 finally:
118 118 ip.Completer.greedy = greedy_original
119 119
120 120
121 121 def test_protect_filename():
122 122 if sys.platform == "win32":
123 123 pairs = [
124 124 ("abc", "abc"),
125 125 (" abc", '" abc"'),
126 126 ("a bc", '"a bc"'),
127 127 ("a bc", '"a bc"'),
128 128 (" bc", '" bc"'),
129 129 ]
130 130 else:
131 131 pairs = [
132 132 ("abc", "abc"),
133 133 (" abc", r"\ abc"),
134 134 ("a bc", r"a\ bc"),
135 135 ("a bc", r"a\ \ bc"),
136 136 (" bc", r"\ \ bc"),
137 137 # On posix, we also protect parens and other special characters.
138 138 ("a(bc", r"a\(bc"),
139 139 ("a)bc", r"a\)bc"),
140 140 ("a( )bc", r"a\(\ \)bc"),
141 141 ("a[1]bc", r"a\[1\]bc"),
142 142 ("a{1}bc", r"a\{1\}bc"),
143 143 ("a#bc", r"a\#bc"),
144 144 ("a?bc", r"a\?bc"),
145 145 ("a=bc", r"a\=bc"),
146 146 ("a\\bc", r"a\\bc"),
147 147 ("a|bc", r"a\|bc"),
148 148 ("a;bc", r"a\;bc"),
149 149 ("a:bc", r"a\:bc"),
150 150 ("a'bc", r"a\'bc"),
151 151 ("a*bc", r"a\*bc"),
152 152 ('a"bc', r"a\"bc"),
153 153 ("a^bc", r"a\^bc"),
154 154 ("a&bc", r"a\&bc"),
155 155 ]
156 156 # run the actual tests
157 157 for s1, s2 in pairs:
158 158 s1p = completer.protect_filename(s1)
159 159 assert s1p == s2
160 160
161 161
162 162 def check_line_split(splitter, test_specs):
163 163 for part1, part2, split in test_specs:
164 164 cursor_pos = len(part1)
165 165 line = part1 + part2
166 166 out = splitter.split_line(line, cursor_pos)
167 167 assert out == split
168 168
169 169
170 170 def test_line_split():
171 171 """Basic line splitter test with default specs."""
172 172 sp = completer.CompletionSplitter()
173 173 # The format of the test specs is: part1, part2, expected answer. Parts 1
174 174 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
175 175 # was at the end of part1. So an empty part2 represents someone hitting
176 176 # tab at the end of the line, the most common case.
177 177 t = [
178 178 ("run some/scrip", "", "some/scrip"),
179 179 ("run scripts/er", "ror.py foo", "scripts/er"),
180 180 ("echo $HOM", "", "HOM"),
181 181 ("print sys.pa", "", "sys.pa"),
182 182 ("print(sys.pa", "", "sys.pa"),
183 183 ("execfile('scripts/er", "", "scripts/er"),
184 184 ("a[x.", "", "x."),
185 185 ("a[x.", "y", "x."),
186 186 ('cd "some_file/', "", "some_file/"),
187 187 ]
188 188 check_line_split(sp, t)
189 189 # Ensure splitting works OK with unicode by re-running the tests with
190 190 # all inputs turned into unicode
191 191 check_line_split(sp, [map(str, p) for p in t])
192 192
193 193
194 194 class NamedInstanceClass:
195 195 instances = {}
196 196
197 197 def __init__(self, name):
198 198 self.instances[name] = self
199 199
200 200 @classmethod
201 201 def _ipython_key_completions_(cls):
202 202 return cls.instances.keys()
203 203
204 204
205 205 class KeyCompletable:
206 206 def __init__(self, things=()):
207 207 self.things = things
208 208
209 209 def _ipython_key_completions_(self):
210 210 return list(self.things)
211 211
212 212
213 @pytest.mark.xfail(
214 sys.version_info >= (3, 11),
215 reason="parso does not support 3.11 yet",
216 raises=NotImplementedError,
217 )
218 213 class TestCompleter(unittest.TestCase):
219 214 def setUp(self):
220 215 """
221 216 We want to silence all PendingDeprecationWarning when testing the completer
222 217 """
223 218 self._assertwarns = self.assertWarns(PendingDeprecationWarning)
224 219 self._assertwarns.__enter__()
225 220
226 221 def tearDown(self):
227 222 try:
228 223 self._assertwarns.__exit__(None, None, None)
229 224 except AssertionError:
230 225 pass
231 226
232 227 def test_custom_completion_error(self):
233 228 """Test that errors from custom attribute completers are silenced."""
234 229 ip = get_ipython()
235 230
236 231 class A:
237 232 pass
238 233
239 234 ip.user_ns["x"] = A()
240 235
241 236 @complete_object.register(A)
242 237 def complete_A(a, existing_completions):
243 238 raise TypeError("this should be silenced")
244 239
245 240 ip.complete("x.")
246 241
247 242 def test_custom_completion_ordering(self):
248 243 """Test that errors from custom attribute completers are silenced."""
249 244 ip = get_ipython()
250 245
251 246 _, matches = ip.complete('in')
252 247 assert matches.index('input') < matches.index('int')
253 248
254 249 def complete_example(a):
255 250 return ['example2', 'example1']
256 251
257 252 ip.Completer.custom_completers.add_re('ex*', complete_example)
258 253 _, matches = ip.complete('ex')
259 254 assert matches.index('example2') < matches.index('example1')
260 255
261 256 def test_unicode_completions(self):
262 257 ip = get_ipython()
263 258 # Some strings that trigger different types of completion. Check them both
264 259 # in str and unicode forms
265 260 s = ["ru", "%ru", "cd /", "floa", "float(x)/"]
266 261 for t in s + list(map(str, s)):
267 262 # We don't need to check exact completion values (they may change
268 263 # depending on the state of the namespace, but at least no exceptions
269 264 # should be thrown and the return value should be a pair of text, list
270 265 # values.
271 266 text, matches = ip.complete(t)
272 267 self.assertIsInstance(text, str)
273 268 self.assertIsInstance(matches, list)
274 269
275 270 def test_latex_completions(self):
276 271 from IPython.core.latex_symbols import latex_symbols
277 272 import random
278 273
279 274 ip = get_ipython()
280 275 # Test some random unicode symbols
281 276 keys = random.sample(sorted(latex_symbols), 10)
282 277 for k in keys:
283 278 text, matches = ip.complete(k)
284 279 self.assertEqual(text, k)
285 280 self.assertEqual(matches, [latex_symbols[k]])
286 281 # Test a more complex line
287 282 text, matches = ip.complete("print(\\alpha")
288 283 self.assertEqual(text, "\\alpha")
289 284 self.assertEqual(matches[0], latex_symbols["\\alpha"])
290 285 # Test multiple matching latex symbols
291 286 text, matches = ip.complete("\\al")
292 287 self.assertIn("\\alpha", matches)
293 288 self.assertIn("\\aleph", matches)
294 289
295 290 def test_latex_no_results(self):
296 291 """
297 292 forward latex should really return nothing in either field if nothing is found.
298 293 """
299 294 ip = get_ipython()
300 295 text, matches = ip.Completer.latex_matches("\\really_i_should_match_nothing")
301 296 self.assertEqual(text, "")
302 297 self.assertEqual(matches, ())
303 298
304 299 def test_back_latex_completion(self):
305 300 ip = get_ipython()
306 301
307 302 # do not return more than 1 matches for \beta, only the latex one.
308 303 name, matches = ip.complete("\\Ξ²")
309 304 self.assertEqual(matches, ["\\beta"])
310 305
311 306 def test_back_unicode_completion(self):
312 307 ip = get_ipython()
313 308
314 309 name, matches = ip.complete("\\β…€")
315 310 self.assertEqual(matches, ("\\ROMAN NUMERAL FIVE",))
316 311
317 312 def test_forward_unicode_completion(self):
318 313 ip = get_ipython()
319 314
320 315 name, matches = ip.complete("\\ROMAN NUMERAL FIVE")
321 316 self.assertEqual(matches, ["β…€"]) # This is not a V
322 317 self.assertEqual(matches, ["\u2164"]) # same as above but explicit.
323 318
324 319 def test_delim_setting(self):
325 320 sp = completer.CompletionSplitter()
326 321 sp.delims = " "
327 322 self.assertEqual(sp.delims, " ")
328 323 self.assertEqual(sp._delim_expr, r"[\ ]")
329 324
330 325 def test_spaces(self):
331 326 """Test with only spaces as split chars."""
332 327 sp = completer.CompletionSplitter()
333 328 sp.delims = " "
334 329 t = [("foo", "", "foo"), ("run foo", "", "foo"), ("run foo", "bar", "foo")]
335 330 check_line_split(sp, t)
336 331
337 332 def test_has_open_quotes1(self):
338 333 for s in ["'", "'''", "'hi' '"]:
339 334 self.assertEqual(completer.has_open_quotes(s), "'")
340 335
341 336 def test_has_open_quotes2(self):
342 337 for s in ['"', '"""', '"hi" "']:
343 338 self.assertEqual(completer.has_open_quotes(s), '"')
344 339
345 340 def test_has_open_quotes3(self):
346 341 for s in ["''", "''' '''", "'hi' 'ipython'"]:
347 342 self.assertFalse(completer.has_open_quotes(s))
348 343
349 344 def test_has_open_quotes4(self):
350 345 for s in ['""', '""" """', '"hi" "ipython"']:
351 346 self.assertFalse(completer.has_open_quotes(s))
352 347
353 348 @pytest.mark.xfail(
354 349 sys.platform == "win32", reason="abspath completions fail on Windows"
355 350 )
356 351 def test_abspath_file_completions(self):
357 352 ip = get_ipython()
358 353 with TemporaryDirectory() as tmpdir:
359 354 prefix = os.path.join(tmpdir, "foo")
360 355 suffixes = ["1", "2"]
361 356 names = [prefix + s for s in suffixes]
362 357 for n in names:
363 358 open(n, "w").close()
364 359
365 360 # Check simple completion
366 361 c = ip.complete(prefix)[1]
367 362 self.assertEqual(c, names)
368 363
369 364 # Now check with a function call
370 365 cmd = 'a = f("%s' % prefix
371 366 c = ip.complete(prefix, cmd)[1]
372 367 comp = [prefix + s for s in suffixes]
373 368 self.assertEqual(c, comp)
374 369
375 370 def test_local_file_completions(self):
376 371 ip = get_ipython()
377 372 with TemporaryWorkingDirectory():
378 373 prefix = "./foo"
379 374 suffixes = ["1", "2"]
380 375 names = [prefix + s for s in suffixes]
381 376 for n in names:
382 377 open(n, "w").close()
383 378
384 379 # Check simple completion
385 380 c = ip.complete(prefix)[1]
386 381 self.assertEqual(c, names)
387 382
388 383 # Now check with a function call
389 384 cmd = 'a = f("%s' % prefix
390 385 c = ip.complete(prefix, cmd)[1]
391 386 comp = {prefix + s for s in suffixes}
392 387 self.assertTrue(comp.issubset(set(c)))
393 388
394 389 def test_quoted_file_completions(self):
395 390 ip = get_ipython()
396 391 with TemporaryWorkingDirectory():
397 392 name = "foo'bar"
398 393 open(name, "w").close()
399 394
400 395 # Don't escape Windows
401 396 escaped = name if sys.platform == "win32" else "foo\\'bar"
402 397
403 398 # Single quote matches embedded single quote
404 399 text = "open('foo"
405 400 c = ip.Completer._complete(
406 401 cursor_line=0, cursor_pos=len(text), full_text=text
407 402 )[1]
408 403 self.assertEqual(c, [escaped])
409 404
410 405 # Double quote requires no escape
411 406 text = 'open("foo'
412 407 c = ip.Completer._complete(
413 408 cursor_line=0, cursor_pos=len(text), full_text=text
414 409 )[1]
415 410 self.assertEqual(c, [name])
416 411
417 412 # No quote requires an escape
418 413 text = "%ls foo"
419 414 c = ip.Completer._complete(
420 415 cursor_line=0, cursor_pos=len(text), full_text=text
421 416 )[1]
422 417 self.assertEqual(c, [escaped])
423 418
424 419 def test_all_completions_dups(self):
425 420 """
426 421 Make sure the output of `IPCompleter.all_completions` does not have
427 422 duplicated prefixes.
428 423 """
429 424 ip = get_ipython()
430 425 c = ip.Completer
431 426 ip.ex("class TestClass():\n\ta=1\n\ta1=2")
432 427 for jedi_status in [True, False]:
433 428 with provisionalcompleter():
434 429 ip.Completer.use_jedi = jedi_status
435 430 matches = c.all_completions("TestCl")
436 431 assert matches == ['TestClass'], jedi_status
437 432 matches = c.all_completions("TestClass.")
438 433 if jedi_status and jedi_issue:
439 434 continue
440 435 assert len(matches) > 2, jedi_status
441 436 matches = c.all_completions("TestClass.a")
442 437 assert matches == ['TestClass.a', 'TestClass.a1'], jedi_status
443 438
444 439 def test_jedi(self):
445 440 """
446 441 A couple of issue we had with Jedi
447 442 """
448 443 ip = get_ipython()
449 444
450 445 def _test_complete(reason, s, comp, start=None, end=None):
451 446 l = len(s)
452 447 start = start if start is not None else l
453 448 end = end if end is not None else l
454 449 with provisionalcompleter():
455 450 ip.Completer.use_jedi = True
456 451 completions = set(ip.Completer.completions(s, l))
457 452 ip.Completer.use_jedi = False
458 453 assert Completion(start, end, comp) in completions, reason
459 454
460 455 def _test_not_complete(reason, s, comp):
461 456 l = len(s)
462 457 with provisionalcompleter():
463 458 ip.Completer.use_jedi = True
464 459 completions = set(ip.Completer.completions(s, l))
465 460 ip.Completer.use_jedi = False
466 461 assert Completion(l, l, comp) not in completions, reason
467 462
468 463 import jedi
469 464
470 465 jedi_version = tuple(int(i) for i in jedi.__version__.split(".")[:3])
471 466 if jedi_version > (0, 10):
472 467 _test_complete("jedi >0.9 should complete and not crash", "a=1;a.", "real")
473 468 _test_complete("can infer first argument", 'a=(1,"foo");a[0].', "real")
474 469 _test_complete("can infer second argument", 'a=(1,"foo");a[1].', "capitalize")
475 470 _test_complete("cover duplicate completions", "im", "import", 0, 2)
476 471
477 472 _test_not_complete("does not mix types", 'a=(1,"foo");a[0].', "capitalize")
478 473
479 474 def test_completion_have_signature(self):
480 475 """
481 476 Lets make sure jedi is capable of pulling out the signature of the function we are completing.
482 477 """
483 478 ip = get_ipython()
484 479 with provisionalcompleter():
485 480 ip.Completer.use_jedi = True
486 481 completions = ip.Completer.completions("ope", 3)
487 482 c = next(completions) # should be `open`
488 483 ip.Completer.use_jedi = False
489 484 assert "file" in c.signature, "Signature of function was not found by completer"
490 485 assert (
491 486 "encoding" in c.signature
492 487 ), "Signature of function was not found by completer"
493 488
494 489 @pytest.mark.xfail(jedi_issue, reason="Known failure on jedi<=0.18.0")
495 490 def test_deduplicate_completions(self):
496 491 """
497 492 Test that completions are correctly deduplicated (even if ranges are not the same)
498 493 """
499 494 ip = get_ipython()
500 495 ip.ex(
501 496 textwrap.dedent(
502 497 """
503 498 class Z:
504 499 zoo = 1
505 500 """
506 501 )
507 502 )
508 503 with provisionalcompleter():
509 504 ip.Completer.use_jedi = True
510 505 l = list(
511 506 _deduplicate_completions("Z.z", ip.Completer.completions("Z.z", 3))
512 507 )
513 508 ip.Completer.use_jedi = False
514 509
515 510 assert len(l) == 1, "Completions (Z.z<tab>) correctly deduplicate: %s " % l
516 511 assert l[0].text == "zoo" # and not `it.accumulate`
517 512
518 513 def test_greedy_completions(self):
519 514 """
520 515 Test the capability of the Greedy completer.
521 516
522 517 Most of the test here does not really show off the greedy completer, for proof
523 518 each of the text below now pass with Jedi. The greedy completer is capable of more.
524 519
525 520 See the :any:`test_dict_key_completion_contexts`
526 521
527 522 """
528 523 ip = get_ipython()
529 524 ip.ex("a=list(range(5))")
530 525 _, c = ip.complete(".", line="a[0].")
531 526 self.assertFalse(".real" in c, "Shouldn't have completed on a[0]: %s" % c)
532 527
533 528 def _(line, cursor_pos, expect, message, completion):
534 529 with greedy_completion(), provisionalcompleter():
535 530 ip.Completer.use_jedi = False
536 531 _, c = ip.complete(".", line=line, cursor_pos=cursor_pos)
537 532 self.assertIn(expect, c, message % c)
538 533
539 534 ip.Completer.use_jedi = True
540 535 with provisionalcompleter():
541 536 completions = ip.Completer.completions(line, cursor_pos)
542 537 self.assertIn(completion, completions)
543 538
544 539 with provisionalcompleter():
545 540 _(
546 541 "a[0].",
547 542 5,
548 543 "a[0].real",
549 544 "Should have completed on a[0].: %s",
550 545 Completion(5, 5, "real"),
551 546 )
552 547 _(
553 548 "a[0].r",
554 549 6,
555 550 "a[0].real",
556 551 "Should have completed on a[0].r: %s",
557 552 Completion(5, 6, "real"),
558 553 )
559 554
560 555 _(
561 556 "a[0].from_",
562 557 10,
563 558 "a[0].from_bytes",
564 559 "Should have completed on a[0].from_: %s",
565 560 Completion(5, 10, "from_bytes"),
566 561 )
567 562
568 563 def test_omit__names(self):
569 564 # also happens to test IPCompleter as a configurable
570 565 ip = get_ipython()
571 566 ip._hidden_attr = 1
572 567 ip._x = {}
573 568 c = ip.Completer
574 569 ip.ex("ip=get_ipython()")
575 570 cfg = Config()
576 571 cfg.IPCompleter.omit__names = 0
577 572 c.update_config(cfg)
578 573 with provisionalcompleter():
579 574 c.use_jedi = False
580 575 s, matches = c.complete("ip.")
581 576 self.assertIn("ip.__str__", matches)
582 577 self.assertIn("ip._hidden_attr", matches)
583 578
584 579 # c.use_jedi = True
585 580 # completions = set(c.completions('ip.', 3))
586 581 # self.assertIn(Completion(3, 3, '__str__'), completions)
587 582 # self.assertIn(Completion(3,3, "_hidden_attr"), completions)
588 583
589 584 cfg = Config()
590 585 cfg.IPCompleter.omit__names = 1
591 586 c.update_config(cfg)
592 587 with provisionalcompleter():
593 588 c.use_jedi = False
594 589 s, matches = c.complete("ip.")
595 590 self.assertNotIn("ip.__str__", matches)
596 591 # self.assertIn('ip._hidden_attr', matches)
597 592
598 593 # c.use_jedi = True
599 594 # completions = set(c.completions('ip.', 3))
600 595 # self.assertNotIn(Completion(3,3,'__str__'), completions)
601 596 # self.assertIn(Completion(3,3, "_hidden_attr"), completions)
602 597
603 598 cfg = Config()
604 599 cfg.IPCompleter.omit__names = 2
605 600 c.update_config(cfg)
606 601 with provisionalcompleter():
607 602 c.use_jedi = False
608 603 s, matches = c.complete("ip.")
609 604 self.assertNotIn("ip.__str__", matches)
610 605 self.assertNotIn("ip._hidden_attr", matches)
611 606
612 607 # c.use_jedi = True
613 608 # completions = set(c.completions('ip.', 3))
614 609 # self.assertNotIn(Completion(3,3,'__str__'), completions)
615 610 # self.assertNotIn(Completion(3,3, "_hidden_attr"), completions)
616 611
617 612 with provisionalcompleter():
618 613 c.use_jedi = False
619 614 s, matches = c.complete("ip._x.")
620 615 self.assertIn("ip._x.keys", matches)
621 616
622 617 # c.use_jedi = True
623 618 # completions = set(c.completions('ip._x.', 6))
624 619 # self.assertIn(Completion(6,6, "keys"), completions)
625 620
626 621 del ip._hidden_attr
627 622 del ip._x
628 623
629 624 def test_limit_to__all__False_ok(self):
630 625 """
631 626 Limit to all is deprecated, once we remove it this test can go away.
632 627 """
633 628 ip = get_ipython()
634 629 c = ip.Completer
635 630 c.use_jedi = False
636 631 ip.ex("class D: x=24")
637 632 ip.ex("d=D()")
638 633 cfg = Config()
639 634 cfg.IPCompleter.limit_to__all__ = False
640 635 c.update_config(cfg)
641 636 s, matches = c.complete("d.")
642 637 self.assertIn("d.x", matches)
643 638
644 639 def test_get__all__entries_ok(self):
645 640 class A:
646 641 __all__ = ["x", 1]
647 642
648 643 words = completer.get__all__entries(A())
649 644 self.assertEqual(words, ["x"])
650 645
651 646 def test_get__all__entries_no__all__ok(self):
652 647 class A:
653 648 pass
654 649
655 650 words = completer.get__all__entries(A())
656 651 self.assertEqual(words, [])
657 652
658 653 def test_func_kw_completions(self):
659 654 ip = get_ipython()
660 655 c = ip.Completer
661 656 c.use_jedi = False
662 657 ip.ex("def myfunc(a=1,b=2): return a+b")
663 658 s, matches = c.complete(None, "myfunc(1,b")
664 659 self.assertIn("b=", matches)
665 660 # Simulate completing with cursor right after b (pos==10):
666 661 s, matches = c.complete(None, "myfunc(1,b)", 10)
667 662 self.assertIn("b=", matches)
668 663 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
669 664 self.assertIn("b=", matches)
670 665 # builtin function
671 666 s, matches = c.complete(None, "min(k, k")
672 667 self.assertIn("key=", matches)
673 668
674 669 def test_default_arguments_from_docstring(self):
675 670 ip = get_ipython()
676 671 c = ip.Completer
677 672 kwd = c._default_arguments_from_docstring("min(iterable[, key=func]) -> value")
678 673 self.assertEqual(kwd, ["key"])
679 674 # with cython type etc
680 675 kwd = c._default_arguments_from_docstring(
681 676 "Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n"
682 677 )
683 678 self.assertEqual(kwd, ["ncall", "resume", "nsplit"])
684 679 # white spaces
685 680 kwd = c._default_arguments_from_docstring(
686 681 "\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n"
687 682 )
688 683 self.assertEqual(kwd, ["ncall", "resume", "nsplit"])
689 684
690 685 def test_line_magics(self):
691 686 ip = get_ipython()
692 687 c = ip.Completer
693 688 s, matches = c.complete(None, "lsmag")
694 689 self.assertIn("%lsmagic", matches)
695 690 s, matches = c.complete(None, "%lsmag")
696 691 self.assertIn("%lsmagic", matches)
697 692
698 693 def test_cell_magics(self):
699 694 from IPython.core.magic import register_cell_magic
700 695
701 696 @register_cell_magic
702 697 def _foo_cellm(line, cell):
703 698 pass
704 699
705 700 ip = get_ipython()
706 701 c = ip.Completer
707 702
708 703 s, matches = c.complete(None, "_foo_ce")
709 704 self.assertIn("%%_foo_cellm", matches)
710 705 s, matches = c.complete(None, "%%_foo_ce")
711 706 self.assertIn("%%_foo_cellm", matches)
712 707
713 708 def test_line_cell_magics(self):
714 709 from IPython.core.magic import register_line_cell_magic
715 710
716 711 @register_line_cell_magic
717 712 def _bar_cellm(line, cell):
718 713 pass
719 714
720 715 ip = get_ipython()
721 716 c = ip.Completer
722 717
723 718 # The policy here is trickier, see comments in completion code. The
724 719 # returned values depend on whether the user passes %% or not explicitly,
725 720 # and this will show a difference if the same name is both a line and cell
726 721 # magic.
727 722 s, matches = c.complete(None, "_bar_ce")
728 723 self.assertIn("%_bar_cellm", matches)
729 724 self.assertIn("%%_bar_cellm", matches)
730 725 s, matches = c.complete(None, "%_bar_ce")
731 726 self.assertIn("%_bar_cellm", matches)
732 727 self.assertIn("%%_bar_cellm", matches)
733 728 s, matches = c.complete(None, "%%_bar_ce")
734 729 self.assertNotIn("%_bar_cellm", matches)
735 730 self.assertIn("%%_bar_cellm", matches)
736 731
737 732 def test_magic_completion_order(self):
738 733 ip = get_ipython()
739 734 c = ip.Completer
740 735
741 736 # Test ordering of line and cell magics.
742 737 text, matches = c.complete("timeit")
743 738 self.assertEqual(matches, ["%timeit", "%%timeit"])
744 739
745 740 def test_magic_completion_shadowing(self):
746 741 ip = get_ipython()
747 742 c = ip.Completer
748 743 c.use_jedi = False
749 744
750 745 # Before importing matplotlib, %matplotlib magic should be the only option.
751 746 text, matches = c.complete("mat")
752 747 self.assertEqual(matches, ["%matplotlib"])
753 748
754 749 # The newly introduced name should shadow the magic.
755 750 ip.run_cell("matplotlib = 1")
756 751 text, matches = c.complete("mat")
757 752 self.assertEqual(matches, ["matplotlib"])
758 753
759 754 # After removing matplotlib from namespace, the magic should again be
760 755 # the only option.
761 756 del ip.user_ns["matplotlib"]
762 757 text, matches = c.complete("mat")
763 758 self.assertEqual(matches, ["%matplotlib"])
764 759
765 760 def test_magic_completion_shadowing_explicit(self):
766 761 """
767 762 If the user try to complete a shadowed magic, and explicit % start should
768 763 still return the completions.
769 764 """
770 765 ip = get_ipython()
771 766 c = ip.Completer
772 767
773 768 # Before importing matplotlib, %matplotlib magic should be the only option.
774 769 text, matches = c.complete("%mat")
775 770 self.assertEqual(matches, ["%matplotlib"])
776 771
777 772 ip.run_cell("matplotlib = 1")
778 773
779 774 # After removing matplotlib from namespace, the magic should still be
780 775 # the only option.
781 776 text, matches = c.complete("%mat")
782 777 self.assertEqual(matches, ["%matplotlib"])
783 778
784 779 def test_magic_config(self):
785 780 ip = get_ipython()
786 781 c = ip.Completer
787 782
788 783 s, matches = c.complete(None, "conf")
789 784 self.assertIn("%config", matches)
790 785 s, matches = c.complete(None, "conf")
791 786 self.assertNotIn("AliasManager", matches)
792 787 s, matches = c.complete(None, "config ")
793 788 self.assertIn("AliasManager", matches)
794 789 s, matches = c.complete(None, "%config ")
795 790 self.assertIn("AliasManager", matches)
796 791 s, matches = c.complete(None, "config Ali")
797 792 self.assertListEqual(["AliasManager"], matches)
798 793 s, matches = c.complete(None, "%config Ali")
799 794 self.assertListEqual(["AliasManager"], matches)
800 795 s, matches = c.complete(None, "config AliasManager")
801 796 self.assertListEqual(["AliasManager"], matches)
802 797 s, matches = c.complete(None, "%config AliasManager")
803 798 self.assertListEqual(["AliasManager"], matches)
804 799 s, matches = c.complete(None, "config AliasManager.")
805 800 self.assertIn("AliasManager.default_aliases", matches)
806 801 s, matches = c.complete(None, "%config AliasManager.")
807 802 self.assertIn("AliasManager.default_aliases", matches)
808 803 s, matches = c.complete(None, "config AliasManager.de")
809 804 self.assertListEqual(["AliasManager.default_aliases"], matches)
810 805 s, matches = c.complete(None, "config AliasManager.de")
811 806 self.assertListEqual(["AliasManager.default_aliases"], matches)
812 807
813 808 def test_magic_color(self):
814 809 ip = get_ipython()
815 810 c = ip.Completer
816 811
817 812 s, matches = c.complete(None, "colo")
818 813 self.assertIn("%colors", matches)
819 814 s, matches = c.complete(None, "colo")
820 815 self.assertNotIn("NoColor", matches)
821 816 s, matches = c.complete(None, "%colors") # No trailing space
822 817 self.assertNotIn("NoColor", matches)
823 818 s, matches = c.complete(None, "colors ")
824 819 self.assertIn("NoColor", matches)
825 820 s, matches = c.complete(None, "%colors ")
826 821 self.assertIn("NoColor", matches)
827 822 s, matches = c.complete(None, "colors NoCo")
828 823 self.assertListEqual(["NoColor"], matches)
829 824 s, matches = c.complete(None, "%colors NoCo")
830 825 self.assertListEqual(["NoColor"], matches)
831 826
832 827 def test_match_dict_keys(self):
833 828 """
834 829 Test that match_dict_keys works on a couple of use case does return what
835 830 expected, and does not crash
836 831 """
837 832 delims = " \t\n`!@#$^&*()=+[{]}\\|;:'\",<>?"
838 833
839 834 keys = ["foo", b"far"]
840 835 assert match_dict_keys(keys, "b'", delims=delims) == ("'", 2, ["far"])
841 836 assert match_dict_keys(keys, "b'f", delims=delims) == ("'", 2, ["far"])
842 837 assert match_dict_keys(keys, 'b"', delims=delims) == ('"', 2, ["far"])
843 838 assert match_dict_keys(keys, 'b"f', delims=delims) == ('"', 2, ["far"])
844 839
845 840 assert match_dict_keys(keys, "'", delims=delims) == ("'", 1, ["foo"])
846 841 assert match_dict_keys(keys, "'f", delims=delims) == ("'", 1, ["foo"])
847 842 assert match_dict_keys(keys, '"', delims=delims) == ('"', 1, ["foo"])
848 843 assert match_dict_keys(keys, '"f', delims=delims) == ('"', 1, ["foo"])
849 844
850 845 match_dict_keys
851 846
852 847 def test_match_dict_keys_tuple(self):
853 848 """
854 849 Test that match_dict_keys called with extra prefix works on a couple of use case,
855 850 does return what expected, and does not crash.
856 851 """
857 852 delims = " \t\n`!@#$^&*()=+[{]}\\|;:'\",<>?"
858 853
859 854 keys = [("foo", "bar"), ("foo", "oof"), ("foo", b"bar"), ('other', 'test')]
860 855
861 856 # Completion on first key == "foo"
862 857 assert match_dict_keys(keys, "'", delims=delims, extra_prefix=("foo",)) == ("'", 1, ["bar", "oof"])
863 858 assert match_dict_keys(keys, "\"", delims=delims, extra_prefix=("foo",)) == ("\"", 1, ["bar", "oof"])
864 859 assert match_dict_keys(keys, "'o", delims=delims, extra_prefix=("foo",)) == ("'", 1, ["oof"])
865 860 assert match_dict_keys(keys, "\"o", delims=delims, extra_prefix=("foo",)) == ("\"", 1, ["oof"])
866 861 assert match_dict_keys(keys, "b'", delims=delims, extra_prefix=("foo",)) == ("'", 2, ["bar"])
867 862 assert match_dict_keys(keys, "b\"", delims=delims, extra_prefix=("foo",)) == ("\"", 2, ["bar"])
868 863 assert match_dict_keys(keys, "b'b", delims=delims, extra_prefix=("foo",)) == ("'", 2, ["bar"])
869 864 assert match_dict_keys(keys, "b\"b", delims=delims, extra_prefix=("foo",)) == ("\"", 2, ["bar"])
870 865
871 866 # No Completion
872 867 assert match_dict_keys(keys, "'", delims=delims, extra_prefix=("no_foo",)) == ("'", 1, [])
873 868 assert match_dict_keys(keys, "'", delims=delims, extra_prefix=("fo",)) == ("'", 1, [])
874 869
875 870 keys = [('foo1', 'foo2', 'foo3', 'foo4'), ('foo1', 'foo2', 'bar', 'foo4')]
876 871 assert match_dict_keys(keys, "'foo", delims=delims, extra_prefix=('foo1',)) == ("'", 1, ["foo2", "foo2"])
877 872 assert match_dict_keys(keys, "'foo", delims=delims, extra_prefix=('foo1', 'foo2')) == ("'", 1, ["foo3"])
878 873 assert match_dict_keys(keys, "'foo", delims=delims, extra_prefix=('foo1', 'foo2', 'foo3')) == ("'", 1, ["foo4"])
879 874 assert match_dict_keys(keys, "'foo", delims=delims, extra_prefix=('foo1', 'foo2', 'foo3', 'foo4')) == ("'", 1, [])
880 875
881 876 def test_dict_key_completion_string(self):
882 877 """Test dictionary key completion for string keys"""
883 878 ip = get_ipython()
884 879 complete = ip.Completer.complete
885 880
886 881 ip.user_ns["d"] = {"abc": None}
887 882
888 883 # check completion at different stages
889 884 _, matches = complete(line_buffer="d[")
890 885 self.assertIn("'abc'", matches)
891 886 self.assertNotIn("'abc']", matches)
892 887
893 888 _, matches = complete(line_buffer="d['")
894 889 self.assertIn("abc", matches)
895 890 self.assertNotIn("abc']", matches)
896 891
897 892 _, matches = complete(line_buffer="d['a")
898 893 self.assertIn("abc", matches)
899 894 self.assertNotIn("abc']", matches)
900 895
901 896 # check use of different quoting
902 897 _, matches = complete(line_buffer='d["')
903 898 self.assertIn("abc", matches)
904 899 self.assertNotIn('abc"]', matches)
905 900
906 901 _, matches = complete(line_buffer='d["a')
907 902 self.assertIn("abc", matches)
908 903 self.assertNotIn('abc"]', matches)
909 904
910 905 # check sensitivity to following context
911 906 _, matches = complete(line_buffer="d[]", cursor_pos=2)
912 907 self.assertIn("'abc'", matches)
913 908
914 909 _, matches = complete(line_buffer="d['']", cursor_pos=3)
915 910 self.assertIn("abc", matches)
916 911 self.assertNotIn("abc'", matches)
917 912 self.assertNotIn("abc']", matches)
918 913
919 914 # check multiple solutions are correctly returned and that noise is not
920 915 ip.user_ns["d"] = {
921 916 "abc": None,
922 917 "abd": None,
923 918 "bad": None,
924 919 object(): None,
925 920 5: None,
926 921 ("abe", None): None,
927 922 (None, "abf"): None
928 923 }
929 924
930 925 _, matches = complete(line_buffer="d['a")
931 926 self.assertIn("abc", matches)
932 927 self.assertIn("abd", matches)
933 928 self.assertNotIn("bad", matches)
934 929 self.assertNotIn("abe", matches)
935 930 self.assertNotIn("abf", matches)
936 931 assert not any(m.endswith(("]", '"', "'")) for m in matches), matches
937 932
938 933 # check escaping and whitespace
939 934 ip.user_ns["d"] = {"a\nb": None, "a'b": None, 'a"b': None, "a word": None}
940 935 _, matches = complete(line_buffer="d['a")
941 936 self.assertIn("a\\nb", matches)
942 937 self.assertIn("a\\'b", matches)
943 938 self.assertIn('a"b', matches)
944 939 self.assertIn("a word", matches)
945 940 assert not any(m.endswith(("]", '"', "'")) for m in matches), matches
946 941
947 942 # - can complete on non-initial word of the string
948 943 _, matches = complete(line_buffer="d['a w")
949 944 self.assertIn("word", matches)
950 945
951 946 # - understands quote escaping
952 947 _, matches = complete(line_buffer="d['a\\'")
953 948 self.assertIn("b", matches)
954 949
955 950 # - default quoting should work like repr
956 951 _, matches = complete(line_buffer="d[")
957 952 self.assertIn('"a\'b"', matches)
958 953
959 954 # - when opening quote with ", possible to match with unescaped apostrophe
960 955 _, matches = complete(line_buffer="d[\"a'")
961 956 self.assertIn("b", matches)
962 957
963 958 # need to not split at delims that readline won't split at
964 959 if "-" not in ip.Completer.splitter.delims:
965 960 ip.user_ns["d"] = {"before-after": None}
966 961 _, matches = complete(line_buffer="d['before-af")
967 962 self.assertIn("before-after", matches)
968 963
969 964 # check completion on tuple-of-string keys at different stage - on first key
970 965 ip.user_ns["d"] = {('foo', 'bar'): None}
971 966 _, matches = complete(line_buffer="d[")
972 967 self.assertIn("'foo'", matches)
973 968 self.assertNotIn("'foo']", matches)
974 969 self.assertNotIn("'bar'", matches)
975 970 self.assertNotIn("foo", matches)
976 971 self.assertNotIn("bar", matches)
977 972
978 973 # - match the prefix
979 974 _, matches = complete(line_buffer="d['f")
980 975 self.assertIn("foo", matches)
981 976 self.assertNotIn("foo']", matches)
982 977 self.assertNotIn('foo"]', matches)
983 978 _, matches = complete(line_buffer="d['foo")
984 979 self.assertIn("foo", matches)
985 980
986 981 # - can complete on second key
987 982 _, matches = complete(line_buffer="d['foo', ")
988 983 self.assertIn("'bar'", matches)
989 984 _, matches = complete(line_buffer="d['foo', 'b")
990 985 self.assertIn("bar", matches)
991 986 self.assertNotIn("foo", matches)
992 987
993 988 # - does not propose missing keys
994 989 _, matches = complete(line_buffer="d['foo', 'f")
995 990 self.assertNotIn("bar", matches)
996 991 self.assertNotIn("foo", matches)
997 992
998 993 # check sensitivity to following context
999 994 _, matches = complete(line_buffer="d['foo',]", cursor_pos=8)
1000 995 self.assertIn("'bar'", matches)
1001 996 self.assertNotIn("bar", matches)
1002 997 self.assertNotIn("'foo'", matches)
1003 998 self.assertNotIn("foo", matches)
1004 999
1005 1000 _, matches = complete(line_buffer="d['']", cursor_pos=3)
1006 1001 self.assertIn("foo", matches)
1007 1002 assert not any(m.endswith(("]", '"', "'")) for m in matches), matches
1008 1003
1009 1004 _, matches = complete(line_buffer='d[""]', cursor_pos=3)
1010 1005 self.assertIn("foo", matches)
1011 1006 assert not any(m.endswith(("]", '"', "'")) for m in matches), matches
1012 1007
1013 1008 _, matches = complete(line_buffer='d["foo","]', cursor_pos=9)
1014 1009 self.assertIn("bar", matches)
1015 1010 assert not any(m.endswith(("]", '"', "'")) for m in matches), matches
1016 1011
1017 1012 _, matches = complete(line_buffer='d["foo",]', cursor_pos=8)
1018 1013 self.assertIn("'bar'", matches)
1019 1014 self.assertNotIn("bar", matches)
1020 1015
1021 1016 # Can complete with longer tuple keys
1022 1017 ip.user_ns["d"] = {('foo', 'bar', 'foobar'): None}
1023 1018
1024 1019 # - can complete second key
1025 1020 _, matches = complete(line_buffer="d['foo', 'b")
1026 1021 self.assertIn("bar", matches)
1027 1022 self.assertNotIn("foo", matches)
1028 1023 self.assertNotIn("foobar", matches)
1029 1024
1030 1025 # - can complete third key
1031 1026 _, matches = complete(line_buffer="d['foo', 'bar', 'fo")
1032 1027 self.assertIn("foobar", matches)
1033 1028 self.assertNotIn("foo", matches)
1034 1029 self.assertNotIn("bar", matches)
1035 1030
1036 1031 def test_dict_key_completion_contexts(self):
1037 1032 """Test expression contexts in which dict key completion occurs"""
1038 1033 ip = get_ipython()
1039 1034 complete = ip.Completer.complete
1040 1035 d = {"abc": None}
1041 1036 ip.user_ns["d"] = d
1042 1037
1043 1038 class C:
1044 1039 data = d
1045 1040
1046 1041 ip.user_ns["C"] = C
1047 1042 ip.user_ns["get"] = lambda: d
1048 1043
1049 1044 def assert_no_completion(**kwargs):
1050 1045 _, matches = complete(**kwargs)
1051 1046 self.assertNotIn("abc", matches)
1052 1047 self.assertNotIn("abc'", matches)
1053 1048 self.assertNotIn("abc']", matches)
1054 1049 self.assertNotIn("'abc'", matches)
1055 1050 self.assertNotIn("'abc']", matches)
1056 1051
1057 1052 def assert_completion(**kwargs):
1058 1053 _, matches = complete(**kwargs)
1059 1054 self.assertIn("'abc'", matches)
1060 1055 self.assertNotIn("'abc']", matches)
1061 1056
1062 1057 # no completion after string closed, even if reopened
1063 1058 assert_no_completion(line_buffer="d['a'")
1064 1059 assert_no_completion(line_buffer='d["a"')
1065 1060 assert_no_completion(line_buffer="d['a' + ")
1066 1061 assert_no_completion(line_buffer="d['a' + '")
1067 1062
1068 1063 # completion in non-trivial expressions
1069 1064 assert_completion(line_buffer="+ d[")
1070 1065 assert_completion(line_buffer="(d[")
1071 1066 assert_completion(line_buffer="C.data[")
1072 1067
1073 1068 # greedy flag
1074 1069 def assert_completion(**kwargs):
1075 1070 _, matches = complete(**kwargs)
1076 1071 self.assertIn("get()['abc']", matches)
1077 1072
1078 1073 assert_no_completion(line_buffer="get()[")
1079 1074 with greedy_completion():
1080 1075 assert_completion(line_buffer="get()[")
1081 1076 assert_completion(line_buffer="get()['")
1082 1077 assert_completion(line_buffer="get()['a")
1083 1078 assert_completion(line_buffer="get()['ab")
1084 1079 assert_completion(line_buffer="get()['abc")
1085 1080
1086 1081 def test_dict_key_completion_bytes(self):
1087 1082 """Test handling of bytes in dict key completion"""
1088 1083 ip = get_ipython()
1089 1084 complete = ip.Completer.complete
1090 1085
1091 1086 ip.user_ns["d"] = {"abc": None, b"abd": None}
1092 1087
1093 1088 _, matches = complete(line_buffer="d[")
1094 1089 self.assertIn("'abc'", matches)
1095 1090 self.assertIn("b'abd'", matches)
1096 1091
1097 1092 if False: # not currently implemented
1098 1093 _, matches = complete(line_buffer="d[b")
1099 1094 self.assertIn("b'abd'", matches)
1100 1095 self.assertNotIn("b'abc'", matches)
1101 1096
1102 1097 _, matches = complete(line_buffer="d[b'")
1103 1098 self.assertIn("abd", matches)
1104 1099 self.assertNotIn("abc", matches)
1105 1100
1106 1101 _, matches = complete(line_buffer="d[B'")
1107 1102 self.assertIn("abd", matches)
1108 1103 self.assertNotIn("abc", matches)
1109 1104
1110 1105 _, matches = complete(line_buffer="d['")
1111 1106 self.assertIn("abc", matches)
1112 1107 self.assertNotIn("abd", matches)
1113 1108
1114 1109 def test_dict_key_completion_unicode_py3(self):
1115 1110 """Test handling of unicode in dict key completion"""
1116 1111 ip = get_ipython()
1117 1112 complete = ip.Completer.complete
1118 1113
1119 1114 ip.user_ns["d"] = {"a\u05d0": None}
1120 1115
1121 1116 # query using escape
1122 1117 if sys.platform != "win32":
1123 1118 # Known failure on Windows
1124 1119 _, matches = complete(line_buffer="d['a\\u05d0")
1125 1120 self.assertIn("u05d0", matches) # tokenized after \\
1126 1121
1127 1122 # query using character
1128 1123 _, matches = complete(line_buffer="d['a\u05d0")
1129 1124 self.assertIn("a\u05d0", matches)
1130 1125
1131 1126 with greedy_completion():
1132 1127 # query using escape
1133 1128 _, matches = complete(line_buffer="d['a\\u05d0")
1134 1129 self.assertIn("d['a\\u05d0']", matches) # tokenized after \\
1135 1130
1136 1131 # query using character
1137 1132 _, matches = complete(line_buffer="d['a\u05d0")
1138 1133 self.assertIn("d['a\u05d0']", matches)
1139 1134
1140 1135 @dec.skip_without("numpy")
1141 1136 def test_struct_array_key_completion(self):
1142 1137 """Test dict key completion applies to numpy struct arrays"""
1143 1138 import numpy
1144 1139
1145 1140 ip = get_ipython()
1146 1141 complete = ip.Completer.complete
1147 1142 ip.user_ns["d"] = numpy.array([], dtype=[("hello", "f"), ("world", "f")])
1148 1143 _, matches = complete(line_buffer="d['")
1149 1144 self.assertIn("hello", matches)
1150 1145 self.assertIn("world", matches)
1151 1146 # complete on the numpy struct itself
1152 1147 dt = numpy.dtype(
1153 1148 [("my_head", [("my_dt", ">u4"), ("my_df", ">u4")]), ("my_data", ">f4", 5)]
1154 1149 )
1155 1150 x = numpy.zeros(2, dtype=dt)
1156 1151 ip.user_ns["d"] = x[1]
1157 1152 _, matches = complete(line_buffer="d['")
1158 1153 self.assertIn("my_head", matches)
1159 1154 self.assertIn("my_data", matches)
1160 1155 # complete on a nested level
1161 1156 with greedy_completion():
1162 1157 ip.user_ns["d"] = numpy.zeros(2, dtype=dt)
1163 1158 _, matches = complete(line_buffer="d[1]['my_head']['")
1164 1159 self.assertTrue(any(["my_dt" in m for m in matches]))
1165 1160 self.assertTrue(any(["my_df" in m for m in matches]))
1166 1161
1167 1162 @dec.skip_without("pandas")
1168 1163 def test_dataframe_key_completion(self):
1169 1164 """Test dict key completion applies to pandas DataFrames"""
1170 1165 import pandas
1171 1166
1172 1167 ip = get_ipython()
1173 1168 complete = ip.Completer.complete
1174 1169 ip.user_ns["d"] = pandas.DataFrame({"hello": [1], "world": [2]})
1175 1170 _, matches = complete(line_buffer="d['")
1176 1171 self.assertIn("hello", matches)
1177 1172 self.assertIn("world", matches)
1178 1173
1179 1174 def test_dict_key_completion_invalids(self):
1180 1175 """Smoke test cases dict key completion can't handle"""
1181 1176 ip = get_ipython()
1182 1177 complete = ip.Completer.complete
1183 1178
1184 1179 ip.user_ns["no_getitem"] = None
1185 1180 ip.user_ns["no_keys"] = []
1186 1181 ip.user_ns["cant_call_keys"] = dict
1187 1182 ip.user_ns["empty"] = {}
1188 1183 ip.user_ns["d"] = {"abc": 5}
1189 1184
1190 1185 _, matches = complete(line_buffer="no_getitem['")
1191 1186 _, matches = complete(line_buffer="no_keys['")
1192 1187 _, matches = complete(line_buffer="cant_call_keys['")
1193 1188 _, matches = complete(line_buffer="empty['")
1194 1189 _, matches = complete(line_buffer="name_error['")
1195 1190 _, matches = complete(line_buffer="d['\\") # incomplete escape
1196 1191
1197 1192 def test_object_key_completion(self):
1198 1193 ip = get_ipython()
1199 1194 ip.user_ns["key_completable"] = KeyCompletable(["qwerty", "qwick"])
1200 1195
1201 1196 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
1202 1197 self.assertIn("qwerty", matches)
1203 1198 self.assertIn("qwick", matches)
1204 1199
1205 1200 def test_class_key_completion(self):
1206 1201 ip = get_ipython()
1207 1202 NamedInstanceClass("qwerty")
1208 1203 NamedInstanceClass("qwick")
1209 1204 ip.user_ns["named_instance_class"] = NamedInstanceClass
1210 1205
1211 1206 _, matches = ip.Completer.complete(line_buffer="named_instance_class['qw")
1212 1207 self.assertIn("qwerty", matches)
1213 1208 self.assertIn("qwick", matches)
1214 1209
1215 1210 def test_tryimport(self):
1216 1211 """
1217 1212 Test that try-import don't crash on trailing dot, and import modules before
1218 1213 """
1219 1214 from IPython.core.completerlib import try_import
1220 1215
1221 1216 assert try_import("IPython.")
1222 1217
1223 1218 def test_aimport_module_completer(self):
1224 1219 ip = get_ipython()
1225 1220 _, matches = ip.complete("i", "%aimport i")
1226 1221 self.assertIn("io", matches)
1227 1222 self.assertNotIn("int", matches)
1228 1223
1229 1224 def test_nested_import_module_completer(self):
1230 1225 ip = get_ipython()
1231 1226 _, matches = ip.complete(None, "import IPython.co", 17)
1232 1227 self.assertIn("IPython.core", matches)
1233 1228 self.assertNotIn("import IPython.core", matches)
1234 1229 self.assertNotIn("IPython.display", matches)
1235 1230
1236 1231 def test_import_module_completer(self):
1237 1232 ip = get_ipython()
1238 1233 _, matches = ip.complete("i", "import i")
1239 1234 self.assertIn("io", matches)
1240 1235 self.assertNotIn("int", matches)
1241 1236
1242 1237 def test_from_module_completer(self):
1243 1238 ip = get_ipython()
1244 1239 _, matches = ip.complete("B", "from io import B", 16)
1245 1240 self.assertIn("BytesIO", matches)
1246 1241 self.assertNotIn("BaseException", matches)
1247 1242
1248 1243 def test_snake_case_completion(self):
1249 1244 ip = get_ipython()
1250 1245 ip.Completer.use_jedi = False
1251 1246 ip.user_ns["some_three"] = 3
1252 1247 ip.user_ns["some_four"] = 4
1253 1248 _, matches = ip.complete("s_", "print(s_f")
1254 1249 self.assertIn("some_three", matches)
1255 1250 self.assertIn("some_four", matches)
1256 1251
1257 1252 def test_mix_terms(self):
1258 1253 ip = get_ipython()
1259 1254 from textwrap import dedent
1260 1255
1261 1256 ip.Completer.use_jedi = False
1262 1257 ip.ex(
1263 1258 dedent(
1264 1259 """
1265 1260 class Test:
1266 1261 def meth(self, meth_arg1):
1267 1262 print("meth")
1268 1263
1269 1264 def meth_1(self, meth1_arg1, meth1_arg2):
1270 1265 print("meth1")
1271 1266
1272 1267 def meth_2(self, meth2_arg1, meth2_arg2):
1273 1268 print("meth2")
1274 1269 test = Test()
1275 1270 """
1276 1271 )
1277 1272 )
1278 1273 _, matches = ip.complete(None, "test.meth(")
1279 1274 self.assertIn("meth_arg1=", matches)
1280 1275 self.assertNotIn("meth2_arg1=", matches)
General Comments 0
You need to be logged in to leave comments. Login now