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