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