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