##// END OF EJS Templates
Skip some failing tests on Windows...
Thomas Kluyver -
Show More
@@ -1,802 +1,807 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 unittest
9 import unittest
10
10
11 from contextlib import contextmanager
11 from contextlib import contextmanager
12
12
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 from traitlets.config.loader import Config
15 from traitlets.config.loader import Config
16 from IPython import get_ipython
16 from IPython import get_ipython
17 from IPython.core import completer
17 from IPython.core import completer
18 from IPython.external.decorators import knownfailureif
18 from IPython.external.decorators import knownfailureif
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 from IPython.utils.generics import complete_object
20 from IPython.utils.generics import complete_object
21 from IPython.utils.py3compat import string_types, unicode_type
21 from IPython.utils.py3compat import string_types, unicode_type
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions
25 # Test functions
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @contextmanager
28 @contextmanager
29 def greedy_completion():
29 def greedy_completion():
30 ip = get_ipython()
30 ip = get_ipython()
31 greedy_original = ip.Completer.greedy
31 greedy_original = ip.Completer.greedy
32 try:
32 try:
33 ip.Completer.greedy = True
33 ip.Completer.greedy = True
34 yield
34 yield
35 finally:
35 finally:
36 ip.Completer.greedy = greedy_original
36 ip.Completer.greedy = greedy_original
37
37
38 def test_protect_filename():
38 def test_protect_filename():
39 if sys.platform == 'win32':
39 if sys.platform == 'win32':
40 pairs = [('abc','abc'),
40 pairs = [('abc','abc'),
41 (' abc','" abc"'),
41 (' abc','" abc"'),
42 ('a bc','"a bc"'),
42 ('a bc','"a bc"'),
43 ('a bc','"a bc"'),
43 ('a bc','"a bc"'),
44 (' bc','" bc"'),
44 (' bc','" bc"'),
45 ]
45 ]
46 else:
46 else:
47 pairs = [('abc','abc'),
47 pairs = [('abc','abc'),
48 (' abc',r'\ abc'),
48 (' abc',r'\ abc'),
49 ('a bc',r'a\ bc'),
49 ('a bc',r'a\ bc'),
50 ('a bc',r'a\ \ bc'),
50 ('a bc',r'a\ \ bc'),
51 (' bc',r'\ \ bc'),
51 (' bc',r'\ \ bc'),
52 # On posix, we also protect parens and other special characters.
52 # On posix, we also protect parens and other special characters.
53 ('a(bc',r'a\(bc'),
53 ('a(bc',r'a\(bc'),
54 ('a)bc',r'a\)bc'),
54 ('a)bc',r'a\)bc'),
55 ('a( )bc',r'a\(\ \)bc'),
55 ('a( )bc',r'a\(\ \)bc'),
56 ('a[1]bc', r'a\[1\]bc'),
56 ('a[1]bc', r'a\[1\]bc'),
57 ('a{1}bc', r'a\{1\}bc'),
57 ('a{1}bc', r'a\{1\}bc'),
58 ('a#bc', r'a\#bc'),
58 ('a#bc', r'a\#bc'),
59 ('a?bc', r'a\?bc'),
59 ('a?bc', r'a\?bc'),
60 ('a=bc', r'a\=bc'),
60 ('a=bc', r'a\=bc'),
61 ('a\\bc', r'a\\bc'),
61 ('a\\bc', r'a\\bc'),
62 ('a|bc', r'a\|bc'),
62 ('a|bc', r'a\|bc'),
63 ('a;bc', r'a\;bc'),
63 ('a;bc', r'a\;bc'),
64 ('a:bc', r'a\:bc'),
64 ('a:bc', r'a\:bc'),
65 ("a'bc", r"a\'bc"),
65 ("a'bc", r"a\'bc"),
66 ('a*bc', r'a\*bc'),
66 ('a*bc', r'a\*bc'),
67 ('a"bc', r'a\"bc'),
67 ('a"bc', r'a\"bc'),
68 ('a^bc', r'a\^bc'),
68 ('a^bc', r'a\^bc'),
69 ('a&bc', r'a\&bc'),
69 ('a&bc', r'a\&bc'),
70 ]
70 ]
71 # run the actual tests
71 # run the actual tests
72 for s1, s2 in pairs:
72 for s1, s2 in pairs:
73 s1p = completer.protect_filename(s1)
73 s1p = completer.protect_filename(s1)
74 nt.assert_equal(s1p, s2)
74 nt.assert_equal(s1p, s2)
75
75
76
76
77 def check_line_split(splitter, test_specs):
77 def check_line_split(splitter, test_specs):
78 for part1, part2, split in test_specs:
78 for part1, part2, split in test_specs:
79 cursor_pos = len(part1)
79 cursor_pos = len(part1)
80 line = part1+part2
80 line = part1+part2
81 out = splitter.split_line(line, cursor_pos)
81 out = splitter.split_line(line, cursor_pos)
82 nt.assert_equal(out, split)
82 nt.assert_equal(out, split)
83
83
84
84
85 def test_line_split():
85 def test_line_split():
86 """Basic line splitter test with default specs."""
86 """Basic line splitter test with default specs."""
87 sp = completer.CompletionSplitter()
87 sp = completer.CompletionSplitter()
88 # The format of the test specs is: part1, part2, expected answer. Parts 1
88 # The format of the test specs is: part1, part2, expected answer. Parts 1
89 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
89 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
90 # was at the end of part1. So an empty part2 represents someone hitting
90 # was at the end of part1. So an empty part2 represents someone hitting
91 # tab at the end of the line, the most common case.
91 # tab at the end of the line, the most common case.
92 t = [('run some/scrip', '', 'some/scrip'),
92 t = [('run some/scrip', '', 'some/scrip'),
93 ('run scripts/er', 'ror.py foo', 'scripts/er'),
93 ('run scripts/er', 'ror.py foo', 'scripts/er'),
94 ('echo $HOM', '', 'HOM'),
94 ('echo $HOM', '', 'HOM'),
95 ('print sys.pa', '', 'sys.pa'),
95 ('print sys.pa', '', 'sys.pa'),
96 ('print(sys.pa', '', 'sys.pa'),
96 ('print(sys.pa', '', 'sys.pa'),
97 ("execfile('scripts/er", '', 'scripts/er'),
97 ("execfile('scripts/er", '', 'scripts/er'),
98 ('a[x.', '', 'x.'),
98 ('a[x.', '', 'x.'),
99 ('a[x.', 'y', 'x.'),
99 ('a[x.', 'y', 'x.'),
100 ('cd "some_file/', '', 'some_file/'),
100 ('cd "some_file/', '', 'some_file/'),
101 ]
101 ]
102 check_line_split(sp, t)
102 check_line_split(sp, t)
103 # Ensure splitting works OK with unicode by re-running the tests with
103 # Ensure splitting works OK with unicode by re-running the tests with
104 # all inputs turned into unicode
104 # all inputs turned into unicode
105 check_line_split(sp, [ map(unicode_type, p) for p in t] )
105 check_line_split(sp, [ map(unicode_type, p) for p in t] )
106
106
107
107
108 def test_custom_completion_error():
108 def test_custom_completion_error():
109 """Test that errors from custom attribute completers are silenced."""
109 """Test that errors from custom attribute completers are silenced."""
110 ip = get_ipython()
110 ip = get_ipython()
111 class A(object): pass
111 class A(object): pass
112 ip.user_ns['a'] = A()
112 ip.user_ns['a'] = A()
113
113
114 @complete_object.when_type(A)
114 @complete_object.when_type(A)
115 def complete_A(a, existing_completions):
115 def complete_A(a, existing_completions):
116 raise TypeError("this should be silenced")
116 raise TypeError("this should be silenced")
117
117
118 ip.complete("a.")
118 ip.complete("a.")
119
119
120
120
121 def test_unicode_completions():
121 def test_unicode_completions():
122 ip = get_ipython()
122 ip = get_ipython()
123 # Some strings that trigger different types of completion. Check them both
123 # Some strings that trigger different types of completion. Check them both
124 # in str and unicode forms
124 # in str and unicode forms
125 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
125 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
126 for t in s + list(map(unicode_type, s)):
126 for t in s + list(map(unicode_type, s)):
127 # We don't need to check exact completion values (they may change
127 # We don't need to check exact completion values (they may change
128 # depending on the state of the namespace, but at least no exceptions
128 # depending on the state of the namespace, but at least no exceptions
129 # should be thrown and the return value should be a pair of text, list
129 # should be thrown and the return value should be a pair of text, list
130 # values.
130 # values.
131 text, matches = ip.complete(t)
131 text, matches = ip.complete(t)
132 nt.assert_true(isinstance(text, string_types))
132 nt.assert_true(isinstance(text, string_types))
133 nt.assert_true(isinstance(matches, list))
133 nt.assert_true(isinstance(matches, list))
134
134
135 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
135 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
136 def test_latex_completions():
136 def test_latex_completions():
137 from IPython.core.latex_symbols import latex_symbols
137 from IPython.core.latex_symbols import latex_symbols
138 import random
138 import random
139 ip = get_ipython()
139 ip = get_ipython()
140 # Test some random unicode symbols
140 # Test some random unicode symbols
141 keys = random.sample(latex_symbols.keys(), 10)
141 keys = random.sample(latex_symbols.keys(), 10)
142 for k in keys:
142 for k in keys:
143 text, matches = ip.complete(k)
143 text, matches = ip.complete(k)
144 nt.assert_equal(len(matches),1)
144 nt.assert_equal(len(matches),1)
145 nt.assert_equal(text, k)
145 nt.assert_equal(text, k)
146 nt.assert_equal(matches[0], latex_symbols[k])
146 nt.assert_equal(matches[0], latex_symbols[k])
147 # Test a more complex line
147 # Test a more complex line
148 text, matches = ip.complete(u'print(\\alpha')
148 text, matches = ip.complete(u'print(\\alpha')
149 nt.assert_equals(text, u'\\alpha')
149 nt.assert_equals(text, u'\\alpha')
150 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
150 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
151 # Test multiple matching latex symbols
151 # Test multiple matching latex symbols
152 text, matches = ip.complete(u'\\al')
152 text, matches = ip.complete(u'\\al')
153 nt.assert_in('\\alpha', matches)
153 nt.assert_in('\\alpha', matches)
154 nt.assert_in('\\aleph', matches)
154 nt.assert_in('\\aleph', matches)
155
155
156
156
157
157
158
158
159 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
159 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
160 def test_back_latex_completion():
160 def test_back_latex_completion():
161 ip = get_ipython()
161 ip = get_ipython()
162
162
163 # do not return more than 1 matches fro \beta, only the latex one.
163 # do not return more than 1 matches fro \beta, only the latex one.
164 name, matches = ip.complete('\\Ξ²')
164 name, matches = ip.complete('\\Ξ²')
165 nt.assert_equal(len(matches), 1)
165 nt.assert_equal(len(matches), 1)
166 nt.assert_equal(matches[0], '\\beta')
166 nt.assert_equal(matches[0], '\\beta')
167
167
168 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
168 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
169 def test_back_unicode_completion():
169 def test_back_unicode_completion():
170 ip = get_ipython()
170 ip = get_ipython()
171
171
172 name, matches = ip.complete('\\β…€')
172 name, matches = ip.complete('\\β…€')
173 nt.assert_equal(len(matches), 1)
173 nt.assert_equal(len(matches), 1)
174 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
174 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
175
175
176
176
177 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
177 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
178 def test_forward_unicode_completion():
178 def test_forward_unicode_completion():
179 ip = get_ipython()
179 ip = get_ipython()
180
180
181 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
181 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
182 nt.assert_equal(len(matches), 1)
182 nt.assert_equal(len(matches), 1)
183 nt.assert_equal(matches[0], 'β…€')
183 nt.assert_equal(matches[0], 'β…€')
184
184
185 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
185 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
186 @dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
186 def test_no_ascii_back_completion():
187 def test_no_ascii_back_completion():
187 ip = get_ipython()
188 ip = get_ipython()
188 with TemporaryWorkingDirectory(): # Avoid any filename completions
189 with TemporaryWorkingDirectory(): # Avoid any filename completions
189 # single ascii letter that don't have yet completions
190 # single ascii letter that don't have yet completions
190 for letter in 'jJ' :
191 for letter in 'jJ' :
191 name, matches = ip.complete('\\'+letter)
192 name, matches = ip.complete('\\'+letter)
192 nt.assert_equal(matches, [])
193 nt.assert_equal(matches, [])
193
194
194
195
195
196
196
197
197 class CompletionSplitterTestCase(unittest.TestCase):
198 class CompletionSplitterTestCase(unittest.TestCase):
198 def setUp(self):
199 def setUp(self):
199 self.sp = completer.CompletionSplitter()
200 self.sp = completer.CompletionSplitter()
200
201
201 def test_delim_setting(self):
202 def test_delim_setting(self):
202 self.sp.delims = ' '
203 self.sp.delims = ' '
203 nt.assert_equal(self.sp.delims, ' ')
204 nt.assert_equal(self.sp.delims, ' ')
204 nt.assert_equal(self.sp._delim_expr, '[\ ]')
205 nt.assert_equal(self.sp._delim_expr, '[\ ]')
205
206
206 def test_spaces(self):
207 def test_spaces(self):
207 """Test with only spaces as split chars."""
208 """Test with only spaces as split chars."""
208 self.sp.delims = ' '
209 self.sp.delims = ' '
209 t = [('foo', '', 'foo'),
210 t = [('foo', '', 'foo'),
210 ('run foo', '', 'foo'),
211 ('run foo', '', 'foo'),
211 ('run foo', 'bar', 'foo'),
212 ('run foo', 'bar', 'foo'),
212 ]
213 ]
213 check_line_split(self.sp, t)
214 check_line_split(self.sp, t)
214
215
215
216
216 def test_has_open_quotes1():
217 def test_has_open_quotes1():
217 for s in ["'", "'''", "'hi' '"]:
218 for s in ["'", "'''", "'hi' '"]:
218 nt.assert_equal(completer.has_open_quotes(s), "'")
219 nt.assert_equal(completer.has_open_quotes(s), "'")
219
220
220
221
221 def test_has_open_quotes2():
222 def test_has_open_quotes2():
222 for s in ['"', '"""', '"hi" "']:
223 for s in ['"', '"""', '"hi" "']:
223 nt.assert_equal(completer.has_open_quotes(s), '"')
224 nt.assert_equal(completer.has_open_quotes(s), '"')
224
225
225
226
226 def test_has_open_quotes3():
227 def test_has_open_quotes3():
227 for s in ["''", "''' '''", "'hi' 'ipython'"]:
228 for s in ["''", "''' '''", "'hi' 'ipython'"]:
228 nt.assert_false(completer.has_open_quotes(s))
229 nt.assert_false(completer.has_open_quotes(s))
229
230
230
231
231 def test_has_open_quotes4():
232 def test_has_open_quotes4():
232 for s in ['""', '""" """', '"hi" "ipython"']:
233 for s in ['""', '""" """', '"hi" "ipython"']:
233 nt.assert_false(completer.has_open_quotes(s))
234 nt.assert_false(completer.has_open_quotes(s))
234
235
235
236
236 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
237 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
237 def test_abspath_file_completions():
238 def test_abspath_file_completions():
238 ip = get_ipython()
239 ip = get_ipython()
239 with TemporaryDirectory() as tmpdir:
240 with TemporaryDirectory() as tmpdir:
240 prefix = os.path.join(tmpdir, 'foo')
241 prefix = os.path.join(tmpdir, 'foo')
241 suffixes = ['1', '2']
242 suffixes = ['1', '2']
242 names = [prefix+s for s in suffixes]
243 names = [prefix+s for s in suffixes]
243 for n in names:
244 for n in names:
244 open(n, 'w').close()
245 open(n, 'w').close()
245
246
246 # Check simple completion
247 # Check simple completion
247 c = ip.complete(prefix)[1]
248 c = ip.complete(prefix)[1]
248 nt.assert_equal(c, names)
249 nt.assert_equal(c, names)
249
250
250 # Now check with a function call
251 # Now check with a function call
251 cmd = 'a = f("%s' % prefix
252 cmd = 'a = f("%s' % prefix
252 c = ip.complete(prefix, cmd)[1]
253 c = ip.complete(prefix, cmd)[1]
253 comp = [prefix+s for s in suffixes]
254 comp = [prefix+s for s in suffixes]
254 nt.assert_equal(c, comp)
255 nt.assert_equal(c, comp)
255
256
256
257
257 def test_local_file_completions():
258 def test_local_file_completions():
258 ip = get_ipython()
259 ip = get_ipython()
259 with TemporaryWorkingDirectory():
260 with TemporaryWorkingDirectory():
260 prefix = './foo'
261 prefix = './foo'
261 suffixes = ['1', '2']
262 suffixes = ['1', '2']
262 names = [prefix+s for s in suffixes]
263 names = [prefix+s for s in suffixes]
263 for n in names:
264 for n in names:
264 open(n, 'w').close()
265 open(n, 'w').close()
265
266
266 # Check simple completion
267 # Check simple completion
267 c = ip.complete(prefix)[1]
268 c = ip.complete(prefix)[1]
268 nt.assert_equal(c, names)
269 nt.assert_equal(c, names)
269
270
270 # Now check with a function call
271 # Now check with a function call
271 cmd = 'a = f("%s' % prefix
272 cmd = 'a = f("%s' % prefix
272 c = ip.complete(prefix, cmd)[1]
273 c = ip.complete(prefix, cmd)[1]
273 comp = set(prefix+s for s in suffixes)
274 comp = set(prefix+s for s in suffixes)
274 nt.assert_true(comp.issubset(set(c)))
275 nt.assert_true(comp.issubset(set(c)))
275
276
276
277
277 def test_greedy_completions():
278 def test_greedy_completions():
278 ip = get_ipython()
279 ip = get_ipython()
279 ip.ex('a=list(range(5))')
280 ip.ex('a=list(range(5))')
280 _,c = ip.complete('.',line='a[0].')
281 _,c = ip.complete('.',line='a[0].')
281 nt.assert_false('.real' in c,
282 nt.assert_false('.real' in c,
282 "Shouldn't have completed on a[0]: %s"%c)
283 "Shouldn't have completed on a[0]: %s"%c)
283 with greedy_completion():
284 with greedy_completion():
284 def _(line, cursor_pos, expect, message):
285 def _(line, cursor_pos, expect, message):
285 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
286 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
286 nt.assert_in(expect, c, message%c)
287 nt.assert_in(expect, c, message%c)
287
288
288 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
289 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
289 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
290 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
290
291
291 if sys.version_info > (3,4):
292 if sys.version_info > (3,4):
292 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
293 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
293
294
294
295
295
296
296 def test_omit__names():
297 def test_omit__names():
297 # also happens to test IPCompleter as a configurable
298 # also happens to test IPCompleter as a configurable
298 ip = get_ipython()
299 ip = get_ipython()
299 ip._hidden_attr = 1
300 ip._hidden_attr = 1
300 ip._x = {}
301 ip._x = {}
301 c = ip.Completer
302 c = ip.Completer
302 ip.ex('ip=get_ipython()')
303 ip.ex('ip=get_ipython()')
303 cfg = Config()
304 cfg = Config()
304 cfg.IPCompleter.omit__names = 0
305 cfg.IPCompleter.omit__names = 0
305 c.update_config(cfg)
306 c.update_config(cfg)
306 s,matches = c.complete('ip.')
307 s,matches = c.complete('ip.')
307 nt.assert_in('ip.__str__', matches)
308 nt.assert_in('ip.__str__', matches)
308 nt.assert_in('ip._hidden_attr', matches)
309 nt.assert_in('ip._hidden_attr', matches)
309 cfg = Config()
310 cfg = Config()
310 cfg.IPCompleter.omit__names = 1
311 cfg.IPCompleter.omit__names = 1
311 c.update_config(cfg)
312 c.update_config(cfg)
312 s,matches = c.complete('ip.')
313 s,matches = c.complete('ip.')
313 nt.assert_not_in('ip.__str__', matches)
314 nt.assert_not_in('ip.__str__', matches)
314 nt.assert_in('ip._hidden_attr', matches)
315 nt.assert_in('ip._hidden_attr', matches)
315 cfg = Config()
316 cfg = Config()
316 cfg.IPCompleter.omit__names = 2
317 cfg.IPCompleter.omit__names = 2
317 c.update_config(cfg)
318 c.update_config(cfg)
318 s,matches = c.complete('ip.')
319 s,matches = c.complete('ip.')
319 nt.assert_not_in('ip.__str__', matches)
320 nt.assert_not_in('ip.__str__', matches)
320 nt.assert_not_in('ip._hidden_attr', matches)
321 nt.assert_not_in('ip._hidden_attr', matches)
321 s,matches = c.complete('ip._x.')
322 s,matches = c.complete('ip._x.')
322 nt.assert_in('ip._x.keys', matches)
323 nt.assert_in('ip._x.keys', matches)
323 del ip._hidden_attr
324 del ip._hidden_attr
324
325
325
326
326 def test_limit_to__all__False_ok():
327 def test_limit_to__all__False_ok():
327 ip = get_ipython()
328 ip = get_ipython()
328 c = ip.Completer
329 c = ip.Completer
329 ip.ex('class D: x=24')
330 ip.ex('class D: x=24')
330 ip.ex('d=D()')
331 ip.ex('d=D()')
331 cfg = Config()
332 cfg = Config()
332 cfg.IPCompleter.limit_to__all__ = False
333 cfg.IPCompleter.limit_to__all__ = False
333 c.update_config(cfg)
334 c.update_config(cfg)
334 s, matches = c.complete('d.')
335 s, matches = c.complete('d.')
335 nt.assert_in('d.x', matches)
336 nt.assert_in('d.x', matches)
336
337
337
338
338 def test_get__all__entries_ok():
339 def test_get__all__entries_ok():
339 class A(object):
340 class A(object):
340 __all__ = ['x', 1]
341 __all__ = ['x', 1]
341 words = completer.get__all__entries(A())
342 words = completer.get__all__entries(A())
342 nt.assert_equal(words, ['x'])
343 nt.assert_equal(words, ['x'])
343
344
344
345
345 def test_get__all__entries_no__all__ok():
346 def test_get__all__entries_no__all__ok():
346 class A(object):
347 class A(object):
347 pass
348 pass
348 words = completer.get__all__entries(A())
349 words = completer.get__all__entries(A())
349 nt.assert_equal(words, [])
350 nt.assert_equal(words, [])
350
351
351
352
352 def test_func_kw_completions():
353 def test_func_kw_completions():
353 ip = get_ipython()
354 ip = get_ipython()
354 c = ip.Completer
355 c = ip.Completer
355 ip.ex('def myfunc(a=1,b=2): return a+b')
356 ip.ex('def myfunc(a=1,b=2): return a+b')
356 s, matches = c.complete(None, 'myfunc(1,b')
357 s, matches = c.complete(None, 'myfunc(1,b')
357 nt.assert_in('b=', matches)
358 nt.assert_in('b=', matches)
358 # Simulate completing with cursor right after b (pos==10):
359 # Simulate completing with cursor right after b (pos==10):
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 nt.assert_in('b=', matches)
361 nt.assert_in('b=', matches)
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 nt.assert_in('b=', matches)
363 nt.assert_in('b=', matches)
363 #builtin function
364 #builtin function
364 s, matches = c.complete(None, 'min(k, k')
365 s, matches = c.complete(None, 'min(k, k')
365 nt.assert_in('key=', matches)
366 nt.assert_in('key=', matches)
366
367
367
368
368 def test_default_arguments_from_docstring():
369 def test_default_arguments_from_docstring():
369 ip = get_ipython()
370 ip = get_ipython()
370 c = ip.Completer
371 c = ip.Completer
371 kwd = c._default_arguments_from_docstring(
372 kwd = c._default_arguments_from_docstring(
372 'min(iterable[, key=func]) -> value')
373 'min(iterable[, key=func]) -> value')
373 nt.assert_equal(kwd, ['key'])
374 nt.assert_equal(kwd, ['key'])
374 #with cython type etc
375 #with cython type etc
375 kwd = c._default_arguments_from_docstring(
376 kwd = c._default_arguments_from_docstring(
376 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
377 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
377 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
378 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
378 #white spaces
379 #white spaces
379 kwd = c._default_arguments_from_docstring(
380 kwd = c._default_arguments_from_docstring(
380 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
381 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
381 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
382 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
382
383
383 def test_line_magics():
384 def test_line_magics():
384 ip = get_ipython()
385 ip = get_ipython()
385 c = ip.Completer
386 c = ip.Completer
386 s, matches = c.complete(None, 'lsmag')
387 s, matches = c.complete(None, 'lsmag')
387 nt.assert_in('%lsmagic', matches)
388 nt.assert_in('%lsmagic', matches)
388 s, matches = c.complete(None, '%lsmag')
389 s, matches = c.complete(None, '%lsmag')
389 nt.assert_in('%lsmagic', matches)
390 nt.assert_in('%lsmagic', matches)
390
391
391
392
392 def test_cell_magics():
393 def test_cell_magics():
393 from IPython.core.magic import register_cell_magic
394 from IPython.core.magic import register_cell_magic
394
395
395 @register_cell_magic
396 @register_cell_magic
396 def _foo_cellm(line, cell):
397 def _foo_cellm(line, cell):
397 pass
398 pass
398
399
399 ip = get_ipython()
400 ip = get_ipython()
400 c = ip.Completer
401 c = ip.Completer
401
402
402 s, matches = c.complete(None, '_foo_ce')
403 s, matches = c.complete(None, '_foo_ce')
403 nt.assert_in('%%_foo_cellm', matches)
404 nt.assert_in('%%_foo_cellm', matches)
404 s, matches = c.complete(None, '%%_foo_ce')
405 s, matches = c.complete(None, '%%_foo_ce')
405 nt.assert_in('%%_foo_cellm', matches)
406 nt.assert_in('%%_foo_cellm', matches)
406
407
407
408
408 def test_line_cell_magics():
409 def test_line_cell_magics():
409 from IPython.core.magic import register_line_cell_magic
410 from IPython.core.magic import register_line_cell_magic
410
411
411 @register_line_cell_magic
412 @register_line_cell_magic
412 def _bar_cellm(line, cell):
413 def _bar_cellm(line, cell):
413 pass
414 pass
414
415
415 ip = get_ipython()
416 ip = get_ipython()
416 c = ip.Completer
417 c = ip.Completer
417
418
418 # The policy here is trickier, see comments in completion code. The
419 # The policy here is trickier, see comments in completion code. The
419 # returned values depend on whether the user passes %% or not explicitly,
420 # returned values depend on whether the user passes %% or not explicitly,
420 # and this will show a difference if the same name is both a line and cell
421 # and this will show a difference if the same name is both a line and cell
421 # magic.
422 # magic.
422 s, matches = c.complete(None, '_bar_ce')
423 s, matches = c.complete(None, '_bar_ce')
423 nt.assert_in('%_bar_cellm', matches)
424 nt.assert_in('%_bar_cellm', matches)
424 nt.assert_in('%%_bar_cellm', matches)
425 nt.assert_in('%%_bar_cellm', matches)
425 s, matches = c.complete(None, '%_bar_ce')
426 s, matches = c.complete(None, '%_bar_ce')
426 nt.assert_in('%_bar_cellm', matches)
427 nt.assert_in('%_bar_cellm', matches)
427 nt.assert_in('%%_bar_cellm', matches)
428 nt.assert_in('%%_bar_cellm', matches)
428 s, matches = c.complete(None, '%%_bar_ce')
429 s, matches = c.complete(None, '%%_bar_ce')
429 nt.assert_not_in('%_bar_cellm', matches)
430 nt.assert_not_in('%_bar_cellm', matches)
430 nt.assert_in('%%_bar_cellm', matches)
431 nt.assert_in('%%_bar_cellm', matches)
431
432
432
433
433 def test_magic_completion_order():
434 def test_magic_completion_order():
434
435
435 ip = get_ipython()
436 ip = get_ipython()
436 c = ip.Completer
437 c = ip.Completer
437
438
438 # Test ordering of magics and non-magics with the same name
439 # Test ordering of magics and non-magics with the same name
439 # We want the non-magic first
440 # We want the non-magic first
440
441
441 # Before importing matplotlib, there should only be one option:
442 # Before importing matplotlib, there should only be one option:
442
443
443 text, matches = c.complete('mat')
444 text, matches = c.complete('mat')
444 nt.assert_equal(matches, ["%matplotlib"])
445 nt.assert_equal(matches, ["%matplotlib"])
445
446
446
447
447 ip.run_cell("matplotlib = 1") # introduce name into namespace
448 ip.run_cell("matplotlib = 1") # introduce name into namespace
448
449
449 # After the import, there should be two options, ordered like this:
450 # After the import, there should be two options, ordered like this:
450 text, matches = c.complete('mat')
451 text, matches = c.complete('mat')
451 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
452 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
452
453
453
454
454 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
455 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
455
456
456 # Order of user variable and line and cell magics with same name:
457 # Order of user variable and line and cell magics with same name:
457 text, matches = c.complete('timeit')
458 text, matches = c.complete('timeit')
458 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
459 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
459
460
460
461
461 def test_dict_key_completion_string():
462 def test_dict_key_completion_string():
462 """Test dictionary key completion for string keys"""
463 """Test dictionary key completion for string keys"""
463 ip = get_ipython()
464 ip = get_ipython()
464 complete = ip.Completer.complete
465 complete = ip.Completer.complete
465
466
466 ip.user_ns['d'] = {'abc': None}
467 ip.user_ns['d'] = {'abc': None}
467
468
468 # check completion at different stages
469 # check completion at different stages
469 _, matches = complete(line_buffer="d[")
470 _, matches = complete(line_buffer="d[")
470 nt.assert_in("'abc'", matches)
471 nt.assert_in("'abc'", matches)
471 nt.assert_not_in("'abc']", matches)
472 nt.assert_not_in("'abc']", matches)
472
473
473 _, matches = complete(line_buffer="d['")
474 _, matches = complete(line_buffer="d['")
474 nt.assert_in("abc", matches)
475 nt.assert_in("abc", matches)
475 nt.assert_not_in("abc']", matches)
476 nt.assert_not_in("abc']", matches)
476
477
477 _, matches = complete(line_buffer="d['a")
478 _, matches = complete(line_buffer="d['a")
478 nt.assert_in("abc", matches)
479 nt.assert_in("abc", matches)
479 nt.assert_not_in("abc']", matches)
480 nt.assert_not_in("abc']", matches)
480
481
481 # check use of different quoting
482 # check use of different quoting
482 _, matches = complete(line_buffer="d[\"")
483 _, matches = complete(line_buffer="d[\"")
483 nt.assert_in("abc", matches)
484 nt.assert_in("abc", matches)
484 nt.assert_not_in('abc\"]', matches)
485 nt.assert_not_in('abc\"]', matches)
485
486
486 _, matches = complete(line_buffer="d[\"a")
487 _, matches = complete(line_buffer="d[\"a")
487 nt.assert_in("abc", matches)
488 nt.assert_in("abc", matches)
488 nt.assert_not_in('abc\"]', matches)
489 nt.assert_not_in('abc\"]', matches)
489
490
490 # check sensitivity to following context
491 # check sensitivity to following context
491 _, matches = complete(line_buffer="d[]", cursor_pos=2)
492 _, matches = complete(line_buffer="d[]", cursor_pos=2)
492 nt.assert_in("'abc'", matches)
493 nt.assert_in("'abc'", matches)
493
494
494 _, matches = complete(line_buffer="d['']", cursor_pos=3)
495 _, matches = complete(line_buffer="d['']", cursor_pos=3)
495 nt.assert_in("abc", matches)
496 nt.assert_in("abc", matches)
496 nt.assert_not_in("abc'", matches)
497 nt.assert_not_in("abc'", matches)
497 nt.assert_not_in("abc']", matches)
498 nt.assert_not_in("abc']", matches)
498
499
499 # check multiple solutions are correctly returned and that noise is not
500 # check multiple solutions are correctly returned and that noise is not
500 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
501 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
501 5: None}
502 5: None}
502
503
503 _, matches = complete(line_buffer="d['a")
504 _, matches = complete(line_buffer="d['a")
504 nt.assert_in("abc", matches)
505 nt.assert_in("abc", matches)
505 nt.assert_in("abd", matches)
506 nt.assert_in("abd", matches)
506 nt.assert_not_in("bad", matches)
507 nt.assert_not_in("bad", matches)
507 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
508 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
508
509
509 # check escaping and whitespace
510 # check escaping and whitespace
510 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
511 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
511 _, matches = complete(line_buffer="d['a")
512 _, matches = complete(line_buffer="d['a")
512 nt.assert_in("a\\nb", matches)
513 nt.assert_in("a\\nb", matches)
513 nt.assert_in("a\\'b", matches)
514 nt.assert_in("a\\'b", matches)
514 nt.assert_in("a\"b", matches)
515 nt.assert_in("a\"b", matches)
515 nt.assert_in("a word", matches)
516 nt.assert_in("a word", matches)
516 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
517 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
517
518
518 # - can complete on non-initial word of the string
519 # - can complete on non-initial word of the string
519 _, matches = complete(line_buffer="d['a w")
520 _, matches = complete(line_buffer="d['a w")
520 nt.assert_in("word", matches)
521 nt.assert_in("word", matches)
521
522
522 # - understands quote escaping
523 # - understands quote escaping
523 _, matches = complete(line_buffer="d['a\\'")
524 _, matches = complete(line_buffer="d['a\\'")
524 nt.assert_in("b", matches)
525 nt.assert_in("b", matches)
525
526
526 # - default quoting should work like repr
527 # - default quoting should work like repr
527 _, matches = complete(line_buffer="d[")
528 _, matches = complete(line_buffer="d[")
528 nt.assert_in("\"a'b\"", matches)
529 nt.assert_in("\"a'b\"", matches)
529
530
530 # - when opening quote with ", possible to match with unescaped apostrophe
531 # - when opening quote with ", possible to match with unescaped apostrophe
531 _, matches = complete(line_buffer="d[\"a'")
532 _, matches = complete(line_buffer="d[\"a'")
532 nt.assert_in("b", matches)
533 nt.assert_in("b", matches)
533
534
534 # need to not split at delims that readline won't split at
535 # need to not split at delims that readline won't split at
535 if '-' not in ip.Completer.splitter.delims:
536 if '-' not in ip.Completer.splitter.delims:
536 ip.user_ns['d'] = {'before-after': None}
537 ip.user_ns['d'] = {'before-after': None}
537 _, matches = complete(line_buffer="d['before-af")
538 _, matches = complete(line_buffer="d['before-af")
538 nt.assert_in('before-after', matches)
539 nt.assert_in('before-after', matches)
539
540
540 def test_dict_key_completion_contexts():
541 def test_dict_key_completion_contexts():
541 """Test expression contexts in which dict key completion occurs"""
542 """Test expression contexts in which dict key completion occurs"""
542 ip = get_ipython()
543 ip = get_ipython()
543 complete = ip.Completer.complete
544 complete = ip.Completer.complete
544 d = {'abc': None}
545 d = {'abc': None}
545 ip.user_ns['d'] = d
546 ip.user_ns['d'] = d
546
547
547 class C:
548 class C:
548 data = d
549 data = d
549 ip.user_ns['C'] = C
550 ip.user_ns['C'] = C
550 ip.user_ns['get'] = lambda: d
551 ip.user_ns['get'] = lambda: d
551
552
552 def assert_no_completion(**kwargs):
553 def assert_no_completion(**kwargs):
553 _, matches = complete(**kwargs)
554 _, matches = complete(**kwargs)
554 nt.assert_not_in('abc', matches)
555 nt.assert_not_in('abc', matches)
555 nt.assert_not_in('abc\'', matches)
556 nt.assert_not_in('abc\'', matches)
556 nt.assert_not_in('abc\']', matches)
557 nt.assert_not_in('abc\']', matches)
557 nt.assert_not_in('\'abc\'', matches)
558 nt.assert_not_in('\'abc\'', matches)
558 nt.assert_not_in('\'abc\']', matches)
559 nt.assert_not_in('\'abc\']', matches)
559
560
560 def assert_completion(**kwargs):
561 def assert_completion(**kwargs):
561 _, matches = complete(**kwargs)
562 _, matches = complete(**kwargs)
562 nt.assert_in("'abc'", matches)
563 nt.assert_in("'abc'", matches)
563 nt.assert_not_in("'abc']", matches)
564 nt.assert_not_in("'abc']", matches)
564
565
565 # no completion after string closed, even if reopened
566 # no completion after string closed, even if reopened
566 assert_no_completion(line_buffer="d['a'")
567 assert_no_completion(line_buffer="d['a'")
567 assert_no_completion(line_buffer="d[\"a\"")
568 assert_no_completion(line_buffer="d[\"a\"")
568 assert_no_completion(line_buffer="d['a' + ")
569 assert_no_completion(line_buffer="d['a' + ")
569 assert_no_completion(line_buffer="d['a' + '")
570 assert_no_completion(line_buffer="d['a' + '")
570
571
571 # completion in non-trivial expressions
572 # completion in non-trivial expressions
572 assert_completion(line_buffer="+ d[")
573 assert_completion(line_buffer="+ d[")
573 assert_completion(line_buffer="(d[")
574 assert_completion(line_buffer="(d[")
574 assert_completion(line_buffer="C.data[")
575 assert_completion(line_buffer="C.data[")
575
576
576 # greedy flag
577 # greedy flag
577 def assert_completion(**kwargs):
578 def assert_completion(**kwargs):
578 _, matches = complete(**kwargs)
579 _, matches = complete(**kwargs)
579 nt.assert_in("get()['abc']", matches)
580 nt.assert_in("get()['abc']", matches)
580
581
581 assert_no_completion(line_buffer="get()[")
582 assert_no_completion(line_buffer="get()[")
582 with greedy_completion():
583 with greedy_completion():
583 assert_completion(line_buffer="get()[")
584 assert_completion(line_buffer="get()[")
584 assert_completion(line_buffer="get()['")
585 assert_completion(line_buffer="get()['")
585 assert_completion(line_buffer="get()['a")
586 assert_completion(line_buffer="get()['a")
586 assert_completion(line_buffer="get()['ab")
587 assert_completion(line_buffer="get()['ab")
587 assert_completion(line_buffer="get()['abc")
588 assert_completion(line_buffer="get()['abc")
588
589
589
590
590
591
591 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
592 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
592 def test_dict_key_completion_bytes():
593 def test_dict_key_completion_bytes():
593 """Test handling of bytes in dict key completion"""
594 """Test handling of bytes in dict key completion"""
594 ip = get_ipython()
595 ip = get_ipython()
595 complete = ip.Completer.complete
596 complete = ip.Completer.complete
596
597
597 ip.user_ns['d'] = {'abc': None, b'abd': None}
598 ip.user_ns['d'] = {'abc': None, b'abd': None}
598
599
599 _, matches = complete(line_buffer="d[")
600 _, matches = complete(line_buffer="d[")
600 nt.assert_in("'abc'", matches)
601 nt.assert_in("'abc'", matches)
601 nt.assert_in("b'abd'", matches)
602 nt.assert_in("b'abd'", matches)
602
603
603 if False: # not currently implemented
604 if False: # not currently implemented
604 _, matches = complete(line_buffer="d[b")
605 _, matches = complete(line_buffer="d[b")
605 nt.assert_in("b'abd'", matches)
606 nt.assert_in("b'abd'", matches)
606 nt.assert_not_in("b'abc'", matches)
607 nt.assert_not_in("b'abc'", matches)
607
608
608 _, matches = complete(line_buffer="d[b'")
609 _, matches = complete(line_buffer="d[b'")
609 nt.assert_in("abd", matches)
610 nt.assert_in("abd", matches)
610 nt.assert_not_in("abc", matches)
611 nt.assert_not_in("abc", matches)
611
612
612 _, matches = complete(line_buffer="d[B'")
613 _, matches = complete(line_buffer="d[B'")
613 nt.assert_in("abd", matches)
614 nt.assert_in("abd", matches)
614 nt.assert_not_in("abc", matches)
615 nt.assert_not_in("abc", matches)
615
616
616 _, matches = complete(line_buffer="d['")
617 _, matches = complete(line_buffer="d['")
617 nt.assert_in("abc", matches)
618 nt.assert_in("abc", matches)
618 nt.assert_not_in("abd", matches)
619 nt.assert_not_in("abd", matches)
619
620
620
621
621 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
622 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
622 def test_dict_key_completion_unicode_py2():
623 def test_dict_key_completion_unicode_py2():
623 """Test handling of unicode in dict key completion"""
624 """Test handling of unicode in dict key completion"""
624 ip = get_ipython()
625 ip = get_ipython()
625 complete = ip.Completer.complete
626 complete = ip.Completer.complete
626
627
627 ip.user_ns['d'] = {u'abc': None,
628 ip.user_ns['d'] = {u'abc': None,
628 u'a\u05d0b': None}
629 u'a\u05d0b': None}
629
630
630 _, matches = complete(line_buffer="d[")
631 _, matches = complete(line_buffer="d[")
631 nt.assert_in("u'abc'", matches)
632 nt.assert_in("u'abc'", matches)
632 nt.assert_in("u'a\\u05d0b'", matches)
633 nt.assert_in("u'a\\u05d0b'", matches)
633
634
634 _, matches = complete(line_buffer="d['a")
635 _, matches = complete(line_buffer="d['a")
635 nt.assert_in("abc", matches)
636 nt.assert_in("abc", matches)
636 nt.assert_not_in("a\\u05d0b", matches)
637 nt.assert_not_in("a\\u05d0b", matches)
637
638
638 _, matches = complete(line_buffer="d[u'a")
639 _, matches = complete(line_buffer="d[u'a")
639 nt.assert_in("abc", matches)
640 nt.assert_in("abc", matches)
640 nt.assert_in("a\\u05d0b", matches)
641 nt.assert_in("a\\u05d0b", matches)
641
642
642 _, matches = complete(line_buffer="d[U'a")
643 _, matches = complete(line_buffer="d[U'a")
643 nt.assert_in("abc", matches)
644 nt.assert_in("abc", matches)
644 nt.assert_in("a\\u05d0b", matches)
645 nt.assert_in("a\\u05d0b", matches)
645
646
646 # query using escape
647 # query using escape
647 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
648 if sys.platform != 'win32':
648 nt.assert_in("u05d0b", matches) # tokenized after \\
649 # Known failure on Windows
650 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
651 nt.assert_in("u05d0b", matches) # tokenized after \\
649
652
650 # query using character
653 # query using character
651 _, matches = complete(line_buffer=u"d[u'a\u05d0")
654 _, matches = complete(line_buffer=u"d[u'a\u05d0")
652 nt.assert_in(u"a\u05d0b", matches)
655 nt.assert_in(u"a\u05d0b", matches)
653
656
654 with greedy_completion():
657 with greedy_completion():
655 _, matches = complete(line_buffer="d[")
658 _, matches = complete(line_buffer="d[")
656 nt.assert_in("d[u'abc']", matches)
659 nt.assert_in("d[u'abc']", matches)
657 nt.assert_in("d[u'a\\u05d0b']", matches)
660 nt.assert_in("d[u'a\\u05d0b']", matches)
658
661
659 _, matches = complete(line_buffer="d['a")
662 _, matches = complete(line_buffer="d['a")
660 nt.assert_in("d['abc']", matches)
663 nt.assert_in("d['abc']", matches)
661 nt.assert_not_in("d[u'a\\u05d0b']", matches)
664 nt.assert_not_in("d[u'a\\u05d0b']", matches)
662
665
663 _, matches = complete(line_buffer="d[u'a")
666 _, matches = complete(line_buffer="d[u'a")
664 nt.assert_in("d[u'abc']", matches)
667 nt.assert_in("d[u'abc']", matches)
665 nt.assert_in("d[u'a\\u05d0b']", matches)
668 nt.assert_in("d[u'a\\u05d0b']", matches)
666
669
667 _, matches = complete(line_buffer="d[U'a")
670 _, matches = complete(line_buffer="d[U'a")
668 nt.assert_in("d[U'abc']", matches)
671 nt.assert_in("d[U'abc']", matches)
669 nt.assert_in("d[U'a\\u05d0b']", matches)
672 nt.assert_in("d[U'a\\u05d0b']", matches)
670
673
671 # query using escape
674 # query using escape
672 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
675 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
673 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
676 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
674
677
675 # query using character
678 # query using character
676 _, matches = complete(line_buffer=u"d[u'a\u05d0")
679 _, matches = complete(line_buffer=u"d[u'a\u05d0")
677 nt.assert_in(u"d[u'a\u05d0b']", matches)
680 nt.assert_in(u"d[u'a\u05d0b']", matches)
678
681
679
682
680 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
683 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
681 def test_dict_key_completion_unicode_py3():
684 def test_dict_key_completion_unicode_py3():
682 """Test handling of unicode in dict key completion"""
685 """Test handling of unicode in dict key completion"""
683 ip = get_ipython()
686 ip = get_ipython()
684 complete = ip.Completer.complete
687 complete = ip.Completer.complete
685
688
686 ip.user_ns['d'] = {u'a\u05d0': None}
689 ip.user_ns['d'] = {u'a\u05d0': None}
687
690
688 # query using escape
691 # query using escape
689 _, matches = complete(line_buffer="d['a\\u05d0")
692 if sys.platform != 'win32':
690 nt.assert_in("u05d0", matches) # tokenized after \\
693 # Known failure on Windows
694 _, matches = complete(line_buffer="d['a\\u05d0")
695 nt.assert_in("u05d0", matches) # tokenized after \\
691
696
692 # query using character
697 # query using character
693 _, matches = complete(line_buffer="d['a\u05d0")
698 _, matches = complete(line_buffer="d['a\u05d0")
694 nt.assert_in(u"a\u05d0", matches)
699 nt.assert_in(u"a\u05d0", matches)
695
700
696 with greedy_completion():
701 with greedy_completion():
697 # query using escape
702 # query using escape
698 _, matches = complete(line_buffer="d['a\\u05d0")
703 _, matches = complete(line_buffer="d['a\\u05d0")
699 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
704 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
700
705
701 # query using character
706 # query using character
702 _, matches = complete(line_buffer="d['a\u05d0")
707 _, matches = complete(line_buffer="d['a\u05d0")
703 nt.assert_in(u"d['a\u05d0']", matches)
708 nt.assert_in(u"d['a\u05d0']", matches)
704
709
705
710
706
711
707 @dec.skip_without('numpy')
712 @dec.skip_without('numpy')
708 def test_struct_array_key_completion():
713 def test_struct_array_key_completion():
709 """Test dict key completion applies to numpy struct arrays"""
714 """Test dict key completion applies to numpy struct arrays"""
710 import numpy
715 import numpy
711 ip = get_ipython()
716 ip = get_ipython()
712 complete = ip.Completer.complete
717 complete = ip.Completer.complete
713 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
718 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
714 _, matches = complete(line_buffer="d['")
719 _, matches = complete(line_buffer="d['")
715 nt.assert_in("hello", matches)
720 nt.assert_in("hello", matches)
716 nt.assert_in("world", matches)
721 nt.assert_in("world", matches)
717 # complete on the numpy struct itself
722 # complete on the numpy struct itself
718 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
723 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
719 ('my_data', '>f4', 5)])
724 ('my_data', '>f4', 5)])
720 x = numpy.zeros(2, dtype=dt)
725 x = numpy.zeros(2, dtype=dt)
721 ip.user_ns['d'] = x[1]
726 ip.user_ns['d'] = x[1]
722 _, matches = complete(line_buffer="d['")
727 _, matches = complete(line_buffer="d['")
723 nt.assert_in("my_head", matches)
728 nt.assert_in("my_head", matches)
724 nt.assert_in("my_data", matches)
729 nt.assert_in("my_data", matches)
725 # complete on a nested level
730 # complete on a nested level
726 with greedy_completion():
731 with greedy_completion():
727 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
732 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
728 _, matches = complete(line_buffer="d[1]['my_head']['")
733 _, matches = complete(line_buffer="d[1]['my_head']['")
729 nt.assert_true(any(["my_dt" in m for m in matches]))
734 nt.assert_true(any(["my_dt" in m for m in matches]))
730 nt.assert_true(any(["my_df" in m for m in matches]))
735 nt.assert_true(any(["my_df" in m for m in matches]))
731
736
732
737
733 @dec.skip_without('pandas')
738 @dec.skip_without('pandas')
734 def test_dataframe_key_completion():
739 def test_dataframe_key_completion():
735 """Test dict key completion applies to pandas DataFrames"""
740 """Test dict key completion applies to pandas DataFrames"""
736 import pandas
741 import pandas
737 ip = get_ipython()
742 ip = get_ipython()
738 complete = ip.Completer.complete
743 complete = ip.Completer.complete
739 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
744 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
740 _, matches = complete(line_buffer="d['")
745 _, matches = complete(line_buffer="d['")
741 nt.assert_in("hello", matches)
746 nt.assert_in("hello", matches)
742 nt.assert_in("world", matches)
747 nt.assert_in("world", matches)
743
748
744
749
745 def test_dict_key_completion_invalids():
750 def test_dict_key_completion_invalids():
746 """Smoke test cases dict key completion can't handle"""
751 """Smoke test cases dict key completion can't handle"""
747 ip = get_ipython()
752 ip = get_ipython()
748 complete = ip.Completer.complete
753 complete = ip.Completer.complete
749
754
750 ip.user_ns['no_getitem'] = None
755 ip.user_ns['no_getitem'] = None
751 ip.user_ns['no_keys'] = []
756 ip.user_ns['no_keys'] = []
752 ip.user_ns['cant_call_keys'] = dict
757 ip.user_ns['cant_call_keys'] = dict
753 ip.user_ns['empty'] = {}
758 ip.user_ns['empty'] = {}
754 ip.user_ns['d'] = {'abc': 5}
759 ip.user_ns['d'] = {'abc': 5}
755
760
756 _, matches = complete(line_buffer="no_getitem['")
761 _, matches = complete(line_buffer="no_getitem['")
757 _, matches = complete(line_buffer="no_keys['")
762 _, matches = complete(line_buffer="no_keys['")
758 _, matches = complete(line_buffer="cant_call_keys['")
763 _, matches = complete(line_buffer="cant_call_keys['")
759 _, matches = complete(line_buffer="empty['")
764 _, matches = complete(line_buffer="empty['")
760 _, matches = complete(line_buffer="name_error['")
765 _, matches = complete(line_buffer="name_error['")
761 _, matches = complete(line_buffer="d['\\") # incomplete escape
766 _, matches = complete(line_buffer="d['\\") # incomplete escape
762
767
763 class KeyCompletable(object):
768 class KeyCompletable(object):
764 def __init__(self, things=()):
769 def __init__(self, things=()):
765 self.things = things
770 self.things = things
766
771
767 def _ipython_key_completions_(self):
772 def _ipython_key_completions_(self):
768 return list(self.things)
773 return list(self.things)
769
774
770 def test_object_key_completion():
775 def test_object_key_completion():
771 ip = get_ipython()
776 ip = get_ipython()
772 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
777 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
773
778
774 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
779 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
775 nt.assert_in('qwerty', matches)
780 nt.assert_in('qwerty', matches)
776 nt.assert_in('qwick', matches)
781 nt.assert_in('qwick', matches)
777
782
778
783
779 def test_aimport_module_completer():
784 def test_aimport_module_completer():
780 ip = get_ipython()
785 ip = get_ipython()
781 _, matches = ip.complete('i', '%aimport i')
786 _, matches = ip.complete('i', '%aimport i')
782 nt.assert_in('io', matches)
787 nt.assert_in('io', matches)
783 nt.assert_not_in('int', matches)
788 nt.assert_not_in('int', matches)
784
789
785 def test_nested_import_module_completer():
790 def test_nested_import_module_completer():
786 ip = get_ipython()
791 ip = get_ipython()
787 _, matches = ip.complete(None, 'import IPython.co', 17)
792 _, matches = ip.complete(None, 'import IPython.co', 17)
788 nt.assert_in('IPython.core', matches)
793 nt.assert_in('IPython.core', matches)
789 nt.assert_not_in('import IPython.core', matches)
794 nt.assert_not_in('import IPython.core', matches)
790 nt.assert_not_in('IPython.display', matches)
795 nt.assert_not_in('IPython.display', matches)
791
796
792 def test_import_module_completer():
797 def test_import_module_completer():
793 ip = get_ipython()
798 ip = get_ipython()
794 _, matches = ip.complete('i', 'import i')
799 _, matches = ip.complete('i', 'import i')
795 nt.assert_in('io', matches)
800 nt.assert_in('io', matches)
796 nt.assert_not_in('int', matches)
801 nt.assert_not_in('int', matches)
797
802
798 def test_from_module_completer():
803 def test_from_module_completer():
799 ip = get_ipython()
804 ip = get_ipython()
800 _, matches = ip.complete('B', 'from io import B', 16)
805 _, matches = ip.complete('B', 'from io import B', 16)
801 nt.assert_in('BytesIO', matches)
806 nt.assert_in('BytesIO', matches)
802 nt.assert_not_in('BaseException', matches)
807 nt.assert_not_in('BaseException', matches)
General Comments 0
You need to be logged in to leave comments. Login now