Show More
@@ -79,6 +79,7 from IPython.config.configurable import Configurable | |||||
79 | from IPython.core.error import TryNext |
|
79 | from IPython.core.error import TryNext | |
80 | from IPython.core.inputsplitter import ESC_MAGIC |
|
80 | from IPython.core.inputsplitter import ESC_MAGIC | |
81 | from IPython.utils import generics |
|
81 | from IPython.utils import generics | |
|
82 | from IPython.utils import io | |||
82 | from IPython.utils.dir2 import dir2 |
|
83 | from IPython.utils.dir2 import dir2 | |
83 | from IPython.utils.process import arg_split |
|
84 | from IPython.utils.process import arg_split | |
84 | from IPython.utils.py3compat import builtin_mod, string_types |
|
85 | from IPython.utils.py3compat import builtin_mod, string_types | |
@@ -429,16 +430,18 def get__all__entries(obj): | |||||
429 | def match_dict_keys(keys, prefix): |
|
430 | def match_dict_keys(keys, prefix): | |
430 | """Used by dict_key_matches, matching the prefix to a list of keys""" |
|
431 | """Used by dict_key_matches, matching the prefix to a list of keys""" | |
431 | if not prefix: |
|
432 | if not prefix: | |
432 | return None, [repr(k) for k in keys |
|
433 | return None, 0, [repr(k) for k in keys | |
433 | if isinstance(k, (string_types, bytes))] |
|
434 | if isinstance(k, (string_types, bytes))] | |
434 | quote_match = re.search('["\']', prefix) |
|
435 | quote_match = re.search('["\']', prefix) | |
435 | quote = quote_match.group() |
|
436 | quote = quote_match.group() | |
436 | try: |
|
437 | try: | |
437 | prefix_str = eval(prefix + quote, {}) |
|
438 | prefix_str = eval(prefix + quote, {}) | |
438 | except Exception: |
|
439 | except Exception: | |
439 | return None, [] |
|
440 | return None, 0, [] | |
440 |
|
441 | |||
441 |
token_ |
|
442 | token_match = re.search(r'\w*$', prefix, re.UNICODE) | |
|
443 | token_start = token_match.start() | |||
|
444 | token_prefix = token_match.group() | |||
442 |
|
445 | |||
443 | # TODO: support bytes in Py3k |
|
446 | # TODO: support bytes in Py3k | |
444 | matched = [] |
|
447 | matched = [] | |
@@ -471,7 +474,7 def match_dict_keys(keys, prefix): | |||||
471 |
|
474 | |||
472 | # then reinsert prefix from start of token |
|
475 | # then reinsert prefix from start of token | |
473 | matched.append('%s%s' % (token_prefix, rem_repr)) |
|
476 | matched.append('%s%s' % (token_prefix, rem_repr)) | |
474 | return quote, matched |
|
477 | return quote, token_start, matched | |
475 |
|
478 | |||
476 |
|
479 | |||
477 | def _safe_isinstance(obj, module, class_name): |
|
480 | def _safe_isinstance(obj, module, class_name): | |
@@ -919,17 +922,47 class IPCompleter(Completer): | |||||
919 | keys = get_keys(obj) |
|
922 | keys = get_keys(obj) | |
920 | if not keys: |
|
923 | if not keys: | |
921 | return keys |
|
924 | return keys | |
922 | closing_quote, matches = match_dict_keys(keys, prefix) |
|
925 | closing_quote, token_offset, matches = match_dict_keys(keys, prefix) | |
|
926 | if not matches: | |||
|
927 | return matches | |||
|
928 | ||||
|
929 | # get the cursor position of | |||
|
930 | # - the text being completed | |||
|
931 | # - the start of the key text | |||
|
932 | # - the start of the completion | |||
|
933 | text_start = len(self.text_until_cursor) - len(text) | |||
|
934 | if prefix: | |||
|
935 | key_start = match.start(2) | |||
|
936 | completion_start = key_start + token_offset | |||
|
937 | else: | |||
|
938 | key_start = completion_start = match.end() | |||
|
939 | ||||
|
940 | # grab the leading prefix, to make sure all completions start with `text` | |||
|
941 | if text_start > key_start: | |||
|
942 | leading = '' | |||
|
943 | else: | |||
|
944 | leading = text[text_start:completion_start] | |||
|
945 | ||||
|
946 | # the index of the `[` character | |||
|
947 | bracket_idx = match.end(1) | |||
923 |
|
948 | |||
924 | # append closing quote and bracket as appropriate |
|
949 | # append closing quote and bracket as appropriate | |
|
950 | # this is *not* appropriate if the opening quote or bracket is outside | |||
|
951 | # the text given to this method | |||
|
952 | suf = '' | |||
925 | continuation = self.line_buffer[len(self.text_until_cursor):] |
|
953 | continuation = self.line_buffer[len(self.text_until_cursor):] | |
926 | if closing_quote and continuation.startswith(closing_quote): |
|
954 | if key_start > text_start and closing_quote: | |
927 | suf = '' |
|
955 | # quotes were opened inside text, maybe close them | |
928 |
|
|
956 | if continuation.startswith(closing_quote): | |
929 | suf = closing_quote or '' |
|
957 | continuation = continuation[len(closing_quote):] | |
930 | else: |
|
958 | else: | |
931 |
suf = |
|
959 | suf += closing_quote | |
932 | return [k + suf for k in matches] |
|
960 | if bracket_idx > text_start: | |
|
961 | # brackets were opened inside text, maybe close them | |||
|
962 | if not continuation.startswith(']'): | |||
|
963 | suf += ']' | |||
|
964 | ||||
|
965 | return [leading + k + suf for k in matches] | |||
933 |
|
966 | |||
934 | def dispatch_custom_completer(self, text): |
|
967 | def dispatch_custom_completer(self, text): | |
935 | #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg |
|
968 | #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg |
@@ -1,18 +1,17 | |||||
1 | """Tests for the IPython tab-completion machinery. |
|
1 | # encoding: utf-8 | |
2 | """ |
|
2 | """Tests for the IPython tab-completion machinery.""" | |
3 | #----------------------------------------------------------------------------- |
|
3 | ||
4 | # Module imports |
|
4 | # Copyright (c) IPython Development Team. | |
5 | #----------------------------------------------------------------------------- |
|
5 | # Distributed under the terms of the Modified BSD License. | |
6 |
|
6 | |||
7 | # stdlib |
|
|||
8 | import os |
|
7 | import os | |
9 | import sys |
|
8 | import sys | |
10 | import unittest |
|
9 | import unittest | |
11 |
|
10 | |||
12 | # third party |
|
11 | from contextlib import contextmanager | |
|
12 | ||||
13 | import nose.tools as nt |
|
13 | import nose.tools as nt | |
14 |
|
14 | |||
15 | # our own packages |
|
|||
16 | from IPython.config.loader import Config |
|
15 | from IPython.config.loader import Config | |
17 | from IPython.core import completer |
|
16 | from IPython.core import completer | |
18 | from IPython.external.decorators import knownfailureif |
|
17 | from IPython.external.decorators import knownfailureif | |
@@ -25,6 +24,17 from IPython.testing import decorators as dec | |||||
25 | #----------------------------------------------------------------------------- |
|
24 | #----------------------------------------------------------------------------- | |
26 | # Test functions |
|
25 | # Test functions | |
27 | #----------------------------------------------------------------------------- |
|
26 | #----------------------------------------------------------------------------- | |
|
27 | ||||
|
28 | @contextmanager | |||
|
29 | def greedy_completion(): | |||
|
30 | ip = get_ipython() | |||
|
31 | greedy_original = ip.Completer.greedy | |||
|
32 | try: | |||
|
33 | ip.Completer.greedy = True | |||
|
34 | yield | |||
|
35 | finally: | |||
|
36 | ip.Completer.greedy = greedy_original | |||
|
37 | ||||
28 | def test_protect_filename(): |
|
38 | def test_protect_filename(): | |
29 | pairs = [ ('abc','abc'), |
|
39 | pairs = [ ('abc','abc'), | |
30 | (' abc',r'\ abc'), |
|
40 | (' abc',r'\ abc'), | |
@@ -205,18 +215,13 def test_local_file_completions(): | |||||
205 |
|
215 | |||
206 | def test_greedy_completions(): |
|
216 | def test_greedy_completions(): | |
207 | ip = get_ipython() |
|
217 | ip = get_ipython() | |
208 | greedy_original = ip.Completer.greedy |
|
218 | ip.ex('a=list(range(5))') | |
209 | try: |
|
219 | _,c = ip.complete('.',line='a[0].') | |
210 | ip.Completer.greedy = False |
|
220 | nt.assert_false('a[0].real' in c, | |
211 | ip.ex('a=list(range(5))') |
|
221 | "Shouldn't have completed on a[0]: %s"%c) | |
212 | _,c = ip.complete('.',line='a[0].') |
|
222 | with greedy_completion(): | |
213 | nt.assert_false('a[0].real' in c, |
|
|||
214 | "Shouldn't have completed on a[0]: %s"%c) |
|
|||
215 | ip.Completer.greedy = True |
|
|||
216 | _,c = ip.complete('.',line='a[0].') |
|
223 | _,c = ip.complete('.',line='a[0].') | |
217 | nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c) |
|
224 | nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c) | |
218 | finally: |
|
|||
219 | ip.Completer.greedy = greedy_original |
|
|||
220 |
|
225 | |||
221 |
|
226 | |||
222 | def test_omit__names(): |
|
227 | def test_omit__names(): | |
@@ -394,7 +399,6 def test_magic_completion_order(): | |||||
394 | nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"]) |
|
399 | nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"]) | |
395 |
|
400 | |||
396 |
|
401 | |||
397 |
|
||||
398 | def test_dict_key_completion_string(): |
|
402 | def test_dict_key_completion_string(): | |
399 | """Test dictionary key completion for string keys""" |
|
403 | """Test dictionary key completion for string keys""" | |
400 | ip = get_ipython() |
|
404 | ip = get_ipython() | |
@@ -404,20 +408,25 def test_dict_key_completion_string(): | |||||
404 |
|
408 | |||
405 | # check completion at different stages |
|
409 | # check completion at different stages | |
406 | _, matches = complete(line_buffer="d[") |
|
410 | _, matches = complete(line_buffer="d[") | |
407 |
nt.assert_in("'abc' |
|
411 | nt.assert_in("'abc'", matches) | |
|
412 | nt.assert_not_in("'abc']", matches) | |||
408 |
|
413 | |||
409 | _, matches = complete(line_buffer="d['") |
|
414 | _, matches = complete(line_buffer="d['") | |
410 |
nt.assert_in("abc |
|
415 | nt.assert_in("abc", matches) | |
|
416 | nt.assert_not_in("abc']", matches) | |||
411 |
|
417 | |||
412 | _, matches = complete(line_buffer="d['a") |
|
418 | _, matches = complete(line_buffer="d['a") | |
413 |
nt.assert_in("abc |
|
419 | nt.assert_in("abc", matches) | |
|
420 | nt.assert_not_in("abc']", matches) | |||
414 |
|
421 | |||
415 | # check use of different quoting |
|
422 | # check use of different quoting | |
416 | _, matches = complete(line_buffer="d[\"") |
|
423 | _, matches = complete(line_buffer="d[\"") | |
417 |
nt.assert_in("abc |
|
424 | nt.assert_in("abc", matches) | |
|
425 | nt.assert_not_in('abc\"]', matches) | |||
418 |
|
426 | |||
419 | _, matches = complete(line_buffer="d[\"a") |
|
427 | _, matches = complete(line_buffer="d[\"a") | |
420 |
nt.assert_in("abc |
|
428 | nt.assert_in("abc", matches) | |
|
429 | nt.assert_not_in('abc\"]', matches) | |||
421 |
|
430 | |||
422 | # check sensitivity to following context |
|
431 | # check sensitivity to following context | |
423 | _, matches = complete(line_buffer="d[]", cursor_pos=2) |
|
432 | _, matches = complete(line_buffer="d[]", cursor_pos=2) | |
@@ -425,39 +434,43 def test_dict_key_completion_string(): | |||||
425 |
|
434 | |||
426 | _, matches = complete(line_buffer="d['']", cursor_pos=3) |
|
435 | _, matches = complete(line_buffer="d['']", cursor_pos=3) | |
427 | nt.assert_in("abc", matches) |
|
436 | nt.assert_in("abc", matches) | |
|
437 | nt.assert_not_in("abc'", matches) | |||
|
438 | nt.assert_not_in("abc']", matches) | |||
428 |
|
439 | |||
429 | # check multiple solutions are correctly returned and that noise is not |
|
440 | # check multiple solutions are correctly returned and that noise is not | |
430 | ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None, |
|
441 | ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None, | |
431 | 5: None} |
|
442 | 5: None} | |
432 |
|
443 | |||
433 | _, matches = complete(line_buffer="d['a") |
|
444 | _, matches = complete(line_buffer="d['a") | |
434 |
nt.assert_in("abc |
|
445 | nt.assert_in("abc", matches) | |
435 |
nt.assert_in("abd |
|
446 | nt.assert_in("abd", matches) | |
436 |
nt.assert_not_in("bad |
|
447 | nt.assert_not_in("bad", matches) | |
|
448 | assert not any(m.endswith((']', '"', "'")) for m in matches), matches | |||
437 |
|
449 | |||
438 | # check escaping and whitespace |
|
450 | # check escaping and whitespace | |
439 | ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None} |
|
451 | ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None} | |
440 | _, matches = complete(line_buffer="d['a") |
|
452 | _, matches = complete(line_buffer="d['a") | |
441 |
nt.assert_in("a\\nb |
|
453 | nt.assert_in("a\\nb", matches) | |
442 |
nt.assert_in("a\\'b |
|
454 | nt.assert_in("a\\'b", matches) | |
443 |
nt.assert_in("a\"b |
|
455 | nt.assert_in("a\"b", matches) | |
444 |
nt.assert_in("a word |
|
456 | nt.assert_in("a word", matches) | |
|
457 | assert not any(m.endswith((']', '"', "'")) for m in matches), matches | |||
445 |
|
458 | |||
446 | # - can complete on non-initial word of the string |
|
459 | # - can complete on non-initial word of the string | |
447 | _, matches = complete(line_buffer="d['a w") |
|
460 | _, matches = complete(line_buffer="d['a w") | |
448 |
nt.assert_in("word |
|
461 | nt.assert_in("word", matches) | |
449 |
|
462 | |||
450 | # - understands quote escaping |
|
463 | # - understands quote escaping | |
451 | _, matches = complete(line_buffer="d['a\\'") |
|
464 | _, matches = complete(line_buffer="d['a\\'") | |
452 |
nt.assert_in("b |
|
465 | nt.assert_in("b", matches) | |
453 |
|
466 | |||
454 | # - default quoting should work like repr |
|
467 | # - default quoting should work like repr | |
455 | _, matches = complete(line_buffer="d[") |
|
468 | _, matches = complete(line_buffer="d[") | |
456 |
nt.assert_in("\"a'b\" |
|
469 | nt.assert_in("\"a'b\"", matches) | |
457 |
|
470 | |||
458 | # - when opening quote with ", possible to match with unescaped apostrophe |
|
471 | # - when opening quote with ", possible to match with unescaped apostrophe | |
459 | _, matches = complete(line_buffer="d[\"a'") |
|
472 | _, matches = complete(line_buffer="d[\"a'") | |
460 |
nt.assert_in("b |
|
473 | nt.assert_in("b", matches) | |
461 |
|
474 | |||
462 |
|
475 | |||
463 | def test_dict_key_completion_contexts(): |
|
476 | def test_dict_key_completion_contexts(): | |
@@ -482,10 +495,10 def test_dict_key_completion_contexts(): | |||||
482 |
|
495 | |||
483 | def assert_completion(**kwargs): |
|
496 | def assert_completion(**kwargs): | |
484 | _, matches = complete(**kwargs) |
|
497 | _, matches = complete(**kwargs) | |
485 |
nt.assert_in("'abc' |
|
498 | nt.assert_in("'abc'", matches) | |
|
499 | nt.assert_not_in("'abc']", matches) | |||
486 |
|
500 | |||
487 | # no completion after string closed, even if reopened |
|
501 | # no completion after string closed, even if reopened | |
488 | ip.Completer.greedy = False |
|
|||
489 | assert_no_completion(line_buffer="d['a'") |
|
502 | assert_no_completion(line_buffer="d['a'") | |
490 | assert_no_completion(line_buffer="d[\"a\"") |
|
503 | assert_no_completion(line_buffer="d[\"a\"") | |
491 | assert_no_completion(line_buffer="d['a' + ") |
|
504 | assert_no_completion(line_buffer="d['a' + ") | |
@@ -497,9 +510,17 def test_dict_key_completion_contexts(): | |||||
497 | assert_completion(line_buffer="C.data[") |
|
510 | assert_completion(line_buffer="C.data[") | |
498 |
|
511 | |||
499 | # greedy flag |
|
512 | # greedy flag | |
|
513 | def assert_completion(**kwargs): | |||
|
514 | _, matches = complete(**kwargs) | |||
|
515 | nt.assert_in("get()['abc']", matches) | |||
|
516 | ||||
500 | assert_no_completion(line_buffer="get()[") |
|
517 | assert_no_completion(line_buffer="get()[") | |
501 | ip.Completer.greedy = True |
|
518 | with greedy_completion(): | |
502 | assert_completion(line_buffer="get()[") |
|
519 | assert_completion(line_buffer="get()[") | |
|
520 | assert_completion(line_buffer="get()['") | |||
|
521 | assert_completion(line_buffer="get()['a") | |||
|
522 | assert_completion(line_buffer="get()['ab") | |||
|
523 | assert_completion(line_buffer="get()['abc") | |||
503 |
|
524 | |||
504 |
|
525 | |||
505 |
|
526 | |||
@@ -512,25 +533,25 def test_dict_key_completion_bytes(): | |||||
512 | ip.user_ns['d'] = {'abc': None, b'abd': None} |
|
533 | ip.user_ns['d'] = {'abc': None, b'abd': None} | |
513 |
|
534 | |||
514 | _, matches = complete(line_buffer="d[") |
|
535 | _, matches = complete(line_buffer="d[") | |
515 |
nt.assert_in("'abc' |
|
536 | nt.assert_in("'abc'", matches) | |
516 |
nt.assert_in("b'abd' |
|
537 | nt.assert_in("b'abd'", matches) | |
517 |
|
538 | |||
518 | if False: # not currently implemented |
|
539 | if False: # not currently implemented | |
519 | _, matches = complete(line_buffer="d[b") |
|
540 | _, matches = complete(line_buffer="d[b") | |
520 |
nt.assert_in("b'abd' |
|
541 | nt.assert_in("b'abd'", matches) | |
521 |
nt.assert_not_in("b'abc' |
|
542 | nt.assert_not_in("b'abc'", matches) | |
522 |
|
543 | |||
523 | _, matches = complete(line_buffer="d[b'") |
|
544 | _, matches = complete(line_buffer="d[b'") | |
524 |
nt.assert_in("abd |
|
545 | nt.assert_in("abd", matches) | |
525 |
nt.assert_not_in("abc |
|
546 | nt.assert_not_in("abc", matches) | |
526 |
|
547 | |||
527 | _, matches = complete(line_buffer="d[B'") |
|
548 | _, matches = complete(line_buffer="d[B'") | |
528 |
nt.assert_in("abd |
|
549 | nt.assert_in("abd", matches) | |
529 |
nt.assert_not_in("abc |
|
550 | nt.assert_not_in("abc", matches) | |
530 |
|
551 | |||
531 | _, matches = complete(line_buffer="d['") |
|
552 | _, matches = complete(line_buffer="d['") | |
532 |
nt.assert_in("abc |
|
553 | nt.assert_in("abc", matches) | |
533 |
nt.assert_not_in("abd |
|
554 | nt.assert_not_in("abd", matches) | |
534 |
|
555 | |||
535 |
|
556 | |||
536 | @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3') |
|
557 | @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3') | |
@@ -540,31 +561,56 def test_dict_key_completion_unicode_py2(): | |||||
540 | complete = ip.Completer.complete |
|
561 | complete = ip.Completer.complete | |
541 |
|
562 | |||
542 | ip.user_ns['d'] = {u'abc': None, |
|
563 | ip.user_ns['d'] = {u'abc': None, | |
543 |
u |
|
564 | u'a\u05d0b': None} | |
544 |
|
565 | |||
545 | _, matches = complete(line_buffer="d[") |
|
566 | _, matches = complete(line_buffer="d[") | |
546 |
nt.assert_in("u'abc' |
|
567 | nt.assert_in("u'abc'", matches) | |
547 |
nt.assert_in("u'a\\u05d0' |
|
568 | nt.assert_in("u'a\\u05d0b'", matches) | |
548 |
|
569 | |||
549 | _, matches = complete(line_buffer="d['a") |
|
570 | _, matches = complete(line_buffer="d['a") | |
550 |
nt.assert_in("abc |
|
571 | nt.assert_in("abc", matches) | |
551 |
nt.assert_not_in("a\\u05d0 |
|
572 | nt.assert_not_in("a\\u05d0b", matches) | |
552 |
|
573 | |||
553 | _, matches = complete(line_buffer="d[u'a") |
|
574 | _, matches = complete(line_buffer="d[u'a") | |
554 |
nt.assert_in("abc |
|
575 | nt.assert_in("abc", matches) | |
555 |
nt.assert_in("a\\u05d0 |
|
576 | nt.assert_in("a\\u05d0b", matches) | |
556 |
|
577 | |||
557 | _, matches = complete(line_buffer="d[U'a") |
|
578 | _, matches = complete(line_buffer="d[U'a") | |
558 |
nt.assert_in("abc |
|
579 | nt.assert_in("abc", matches) | |
559 |
nt.assert_in("a\\u05d0 |
|
580 | nt.assert_in("a\\u05d0b", matches) | |
560 |
|
581 | |||
561 | # query using escape |
|
582 | # query using escape | |
562 | _, matches = complete(line_buffer="d[u'a\\u05d0") |
|
583 | _, matches = complete(line_buffer=u"d[u'a\\u05d0") | |
563 |
nt.assert_in("u05d0 |
|
584 | nt.assert_in("u05d0b", matches) # tokenized after \\ | |
564 |
|
585 | |||
565 | # query using character |
|
586 | # query using character | |
566 |
_, matches = complete(line_buffer=u |
|
587 | _, matches = complete(line_buffer=u"d[u'a\u05d0") | |
567 |
nt.assert_in(" |
|
588 | nt.assert_in(u"a\u05d0b", matches) | |
|
589 | ||||
|
590 | with greedy_completion(): | |||
|
591 | _, matches = complete(line_buffer="d[") | |||
|
592 | nt.assert_in("d[u'abc']", matches) | |||
|
593 | nt.assert_in("d[u'a\\u05d0b']", matches) | |||
|
594 | ||||
|
595 | _, matches = complete(line_buffer="d['a") | |||
|
596 | nt.assert_in("d['abc']", matches) | |||
|
597 | nt.assert_not_in("d[u'a\\u05d0b']", matches) | |||
|
598 | ||||
|
599 | _, matches = complete(line_buffer="d[u'a") | |||
|
600 | nt.assert_in("d[u'abc']", matches) | |||
|
601 | nt.assert_in("d[u'a\\u05d0b']", matches) | |||
|
602 | ||||
|
603 | _, matches = complete(line_buffer="d[U'a") | |||
|
604 | nt.assert_in("d[U'abc']", matches) | |||
|
605 | nt.assert_in("d[U'a\\u05d0b']", matches) | |||
|
606 | ||||
|
607 | # query using escape | |||
|
608 | _, matches = complete(line_buffer=u"d[u'a\\u05d0") | |||
|
609 | nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\ | |||
|
610 | ||||
|
611 | # query using character | |||
|
612 | _, matches = complete(line_buffer=u"d[u'a\u05d0") | |||
|
613 | nt.assert_in(u"d[u'a\u05d0b']", matches) | |||
568 |
|
614 | |||
569 |
|
615 | |||
570 | @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3') |
|
616 | @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3') | |
@@ -573,15 +619,25 def test_dict_key_completion_unicode_py3(): | |||||
573 | ip = get_ipython() |
|
619 | ip = get_ipython() | |
574 | complete = ip.Completer.complete |
|
620 | complete = ip.Completer.complete | |
575 |
|
621 | |||
576 |
ip.user_ns['d'] = {u |
|
622 | ip.user_ns['d'] = {u'a\u05d0': None} | |
577 |
|
623 | |||
578 | # query using escape |
|
624 | # query using escape | |
579 | _, matches = complete(line_buffer="d['a\\u05d0") |
|
625 | _, matches = complete(line_buffer="d['a\\u05d0") | |
580 |
nt.assert_in("u05d0 |
|
626 | nt.assert_in("u05d0", matches) # tokenized after \\ | |
581 |
|
627 | |||
582 | # query using character |
|
628 | # query using character | |
583 |
_, matches = complete(line_buffer= |
|
629 | _, matches = complete(line_buffer="d['a\u05d0") | |
584 |
nt.assert_in(u |
|
630 | nt.assert_in(u"a\u05d0", matches) | |
|
631 | ||||
|
632 | with greedy_completion(): | |||
|
633 | # query using escape | |||
|
634 | _, matches = complete(line_buffer="d['a\\u05d0") | |||
|
635 | nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\ | |||
|
636 | ||||
|
637 | # query using character | |||
|
638 | _, matches = complete(line_buffer="d['a\u05d0") | |||
|
639 | nt.assert_in(u"d['a\u05d0']", matches) | |||
|
640 | ||||
585 |
|
641 | |||
586 |
|
642 | |||
587 | @dec.skip_without('numpy') |
|
643 | @dec.skip_without('numpy') | |
@@ -592,8 +648,8 def test_struct_array_key_completion(): | |||||
592 | complete = ip.Completer.complete |
|
648 | complete = ip.Completer.complete | |
593 | ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')]) |
|
649 | ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')]) | |
594 | _, matches = complete(line_buffer="d['") |
|
650 | _, matches = complete(line_buffer="d['") | |
595 |
nt.assert_in("hello |
|
651 | nt.assert_in("hello", matches) | |
596 |
nt.assert_in("world |
|
652 | nt.assert_in("world", matches) | |
597 |
|
653 | |||
598 |
|
654 | |||
599 | @dec.skip_without('pandas') |
|
655 | @dec.skip_without('pandas') | |
@@ -604,8 +660,8 def test_dataframe_key_completion(): | |||||
604 | complete = ip.Completer.complete |
|
660 | complete = ip.Completer.complete | |
605 | ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]}) |
|
661 | ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]}) | |
606 | _, matches = complete(line_buffer="d['") |
|
662 | _, matches = complete(line_buffer="d['") | |
607 |
nt.assert_in("hello |
|
663 | nt.assert_in("hello", matches) | |
608 |
nt.assert_in("world |
|
664 | nt.assert_in("world", matches) | |
609 |
|
665 | |||
610 |
|
666 | |||
611 | def test_dict_key_completion_invalids(): |
|
667 | def test_dict_key_completion_invalids(): |
General Comments 0
You need to be logged in to leave comments.
Login now