##// END OF EJS Templates
Merge pull request #9634 from anntzer/fix-windows-quoting-tests...
Thomas Kluyver -
r22568:4e617c3b merge
parent child Browse files
Show More
@@ -1,802 +1,802 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 def test_no_ascii_back_completion():
186 def test_no_ascii_back_completion():
187 ip = get_ipython()
187 ip = get_ipython()
188 with TemporaryWorkingDirectory(): # Avoid any filename completions
188 with TemporaryWorkingDirectory(): # Avoid any filename completions
189 # single ascii letter that don't have yet completions
189 # single ascii letter that don't have yet completions
190 for letter in 'jJ' :
190 for letter in 'jJ' :
191 name, matches = ip.complete('\\'+letter)
191 name, matches = ip.complete('\\'+letter)
192 nt.assert_equal(matches, [])
192 nt.assert_equal(matches, [])
193
193
194
194
195
195
196
196
197 class CompletionSplitterTestCase(unittest.TestCase):
197 class CompletionSplitterTestCase(unittest.TestCase):
198 def setUp(self):
198 def setUp(self):
199 self.sp = completer.CompletionSplitter()
199 self.sp = completer.CompletionSplitter()
200
200
201 def test_delim_setting(self):
201 def test_delim_setting(self):
202 self.sp.delims = ' '
202 self.sp.delims = ' '
203 nt.assert_equal(self.sp.delims, ' ')
203 nt.assert_equal(self.sp.delims, ' ')
204 nt.assert_equal(self.sp._delim_expr, '[\ ]')
204 nt.assert_equal(self.sp._delim_expr, '[\ ]')
205
205
206 def test_spaces(self):
206 def test_spaces(self):
207 """Test with only spaces as split chars."""
207 """Test with only spaces as split chars."""
208 self.sp.delims = ' '
208 self.sp.delims = ' '
209 t = [('foo', '', 'foo'),
209 t = [('foo', '', 'foo'),
210 ('run foo', '', 'foo'),
210 ('run foo', '', 'foo'),
211 ('run foo', 'bar', 'foo'),
211 ('run foo', 'bar', 'foo'),
212 ]
212 ]
213 check_line_split(self.sp, t)
213 check_line_split(self.sp, t)
214
214
215
215
216 def test_has_open_quotes1():
216 def test_has_open_quotes1():
217 for s in ["'", "'''", "'hi' '"]:
217 for s in ["'", "'''", "'hi' '"]:
218 nt.assert_equal(completer.has_open_quotes(s), "'")
218 nt.assert_equal(completer.has_open_quotes(s), "'")
219
219
220
220
221 def test_has_open_quotes2():
221 def test_has_open_quotes2():
222 for s in ['"', '"""', '"hi" "']:
222 for s in ['"', '"""', '"hi" "']:
223 nt.assert_equal(completer.has_open_quotes(s), '"')
223 nt.assert_equal(completer.has_open_quotes(s), '"')
224
224
225
225
226 def test_has_open_quotes3():
226 def test_has_open_quotes3():
227 for s in ["''", "''' '''", "'hi' 'ipython'"]:
227 for s in ["''", "''' '''", "'hi' 'ipython'"]:
228 nt.assert_false(completer.has_open_quotes(s))
228 nt.assert_false(completer.has_open_quotes(s))
229
229
230
230
231 def test_has_open_quotes4():
231 def test_has_open_quotes4():
232 for s in ['""', '""" """', '"hi" "ipython"']:
232 for s in ['""', '""" """', '"hi" "ipython"']:
233 nt.assert_false(completer.has_open_quotes(s))
233 nt.assert_false(completer.has_open_quotes(s))
234
234
235
235
236 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
236 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
237 def test_abspath_file_completions():
237 def test_abspath_file_completions():
238 ip = get_ipython()
238 ip = get_ipython()
239 with TemporaryDirectory() as tmpdir:
239 with TemporaryDirectory() as tmpdir:
240 prefix = os.path.join(tmpdir, 'foo')
240 prefix = os.path.join(tmpdir, 'foo')
241 suffixes = ['1', '2']
241 suffixes = ['1', '2']
242 names = [prefix+s for s in suffixes]
242 names = [prefix+s for s in suffixes]
243 for n in names:
243 for n in names:
244 open(n, 'w').close()
244 open(n, 'w').close()
245
245
246 # Check simple completion
246 # Check simple completion
247 c = ip.complete(prefix)[1]
247 c = ip.complete(prefix)[1]
248 nt.assert_equal(c, names)
248 nt.assert_equal(c, names)
249
249
250 # Now check with a function call
250 # Now check with a function call
251 cmd = 'a = f("%s' % prefix
251 cmd = 'a = f("%s' % prefix
252 c = ip.complete(prefix, cmd)[1]
252 c = ip.complete(prefix, cmd)[1]
253 comp = [prefix+s for s in suffixes]
253 comp = [prefix+s for s in suffixes]
254 nt.assert_equal(c, comp)
254 nt.assert_equal(c, comp)
255
255
256
256
257 def test_local_file_completions():
257 def test_local_file_completions():
258 ip = get_ipython()
258 ip = get_ipython()
259 with TemporaryWorkingDirectory():
259 with TemporaryWorkingDirectory():
260 prefix = './foo'
260 prefix = './foo'
261 suffixes = ['1', '2']
261 suffixes = ['1', '2']
262 names = [prefix+s for s in suffixes]
262 names = [prefix+s for s in suffixes]
263 for n in names:
263 for n in names:
264 open(n, 'w').close()
264 open(n, 'w').close()
265
265
266 # Check simple completion
266 # Check simple completion
267 c = ip.complete(prefix)[1]
267 c = ip.complete(prefix)[1]
268 nt.assert_equal(c, names)
268 nt.assert_equal(c, names)
269
269
270 # Now check with a function call
270 # Now check with a function call
271 cmd = 'a = f("%s' % prefix
271 cmd = 'a = f("%s' % prefix
272 c = ip.complete(prefix, cmd)[1]
272 c = ip.complete(prefix, cmd)[1]
273 comp = set(prefix+s for s in suffixes)
273 comp = set(prefix+s for s in suffixes)
274 nt.assert_true(comp.issubset(set(c)))
274 nt.assert_true(comp.issubset(set(c)))
275
275
276
276
277 def test_greedy_completions():
277 def test_greedy_completions():
278 ip = get_ipython()
278 ip = get_ipython()
279 ip.ex('a=list(range(5))')
279 ip.ex('a=list(range(5))')
280 _,c = ip.complete('.',line='a[0].')
280 _,c = ip.complete('.',line='a[0].')
281 nt.assert_false('.real' in c,
281 nt.assert_false('.real' in c,
282 "Shouldn't have completed on a[0]: %s"%c)
282 "Shouldn't have completed on a[0]: %s"%c)
283 with greedy_completion():
283 with greedy_completion():
284 def _(line, cursor_pos, expect, message):
284 def _(line, cursor_pos, expect, message):
285 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
285 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
286 nt.assert_in(expect, c, message%c)
286 nt.assert_in(expect, c, message%c)
287
287
288 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
288 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"
289 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
290
290
291 if sys.version_info > (3,4):
291 if sys.version_info > (3,4):
292 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
292 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
293
293
294
294
295
295
296 def test_omit__names():
296 def test_omit__names():
297 # also happens to test IPCompleter as a configurable
297 # also happens to test IPCompleter as a configurable
298 ip = get_ipython()
298 ip = get_ipython()
299 ip._hidden_attr = 1
299 ip._hidden_attr = 1
300 ip._x = {}
300 ip._x = {}
301 c = ip.Completer
301 c = ip.Completer
302 ip.ex('ip=get_ipython()')
302 ip.ex('ip=get_ipython()')
303 cfg = Config()
303 cfg = Config()
304 cfg.IPCompleter.omit__names = 0
304 cfg.IPCompleter.omit__names = 0
305 c.update_config(cfg)
305 c.update_config(cfg)
306 s,matches = c.complete('ip.')
306 s,matches = c.complete('ip.')
307 nt.assert_in('ip.__str__', matches)
307 nt.assert_in('ip.__str__', matches)
308 nt.assert_in('ip._hidden_attr', matches)
308 nt.assert_in('ip._hidden_attr', matches)
309 cfg = Config()
309 cfg = Config()
310 cfg.IPCompleter.omit__names = 1
310 cfg.IPCompleter.omit__names = 1
311 c.update_config(cfg)
311 c.update_config(cfg)
312 s,matches = c.complete('ip.')
312 s,matches = c.complete('ip.')
313 nt.assert_not_in('ip.__str__', matches)
313 nt.assert_not_in('ip.__str__', matches)
314 nt.assert_in('ip._hidden_attr', matches)
314 nt.assert_in('ip._hidden_attr', matches)
315 cfg = Config()
315 cfg = Config()
316 cfg.IPCompleter.omit__names = 2
316 cfg.IPCompleter.omit__names = 2
317 c.update_config(cfg)
317 c.update_config(cfg)
318 s,matches = c.complete('ip.')
318 s,matches = c.complete('ip.')
319 nt.assert_not_in('ip.__str__', matches)
319 nt.assert_not_in('ip.__str__', matches)
320 nt.assert_not_in('ip._hidden_attr', matches)
320 nt.assert_not_in('ip._hidden_attr', matches)
321 s,matches = c.complete('ip._x.')
321 s,matches = c.complete('ip._x.')
322 nt.assert_in('ip._x.keys', matches)
322 nt.assert_in('ip._x.keys', matches)
323 del ip._hidden_attr
323 del ip._hidden_attr
324
324
325
325
326 def test_limit_to__all__False_ok():
326 def test_limit_to__all__False_ok():
327 ip = get_ipython()
327 ip = get_ipython()
328 c = ip.Completer
328 c = ip.Completer
329 ip.ex('class D: x=24')
329 ip.ex('class D: x=24')
330 ip.ex('d=D()')
330 ip.ex('d=D()')
331 cfg = Config()
331 cfg = Config()
332 cfg.IPCompleter.limit_to__all__ = False
332 cfg.IPCompleter.limit_to__all__ = False
333 c.update_config(cfg)
333 c.update_config(cfg)
334 s, matches = c.complete('d.')
334 s, matches = c.complete('d.')
335 nt.assert_in('d.x', matches)
335 nt.assert_in('d.x', matches)
336
336
337
337
338 def test_get__all__entries_ok():
338 def test_get__all__entries_ok():
339 class A(object):
339 class A(object):
340 __all__ = ['x', 1]
340 __all__ = ['x', 1]
341 words = completer.get__all__entries(A())
341 words = completer.get__all__entries(A())
342 nt.assert_equal(words, ['x'])
342 nt.assert_equal(words, ['x'])
343
343
344
344
345 def test_get__all__entries_no__all__ok():
345 def test_get__all__entries_no__all__ok():
346 class A(object):
346 class A(object):
347 pass
347 pass
348 words = completer.get__all__entries(A())
348 words = completer.get__all__entries(A())
349 nt.assert_equal(words, [])
349 nt.assert_equal(words, [])
350
350
351
351
352 def test_func_kw_completions():
352 def test_func_kw_completions():
353 ip = get_ipython()
353 ip = get_ipython()
354 c = ip.Completer
354 c = ip.Completer
355 ip.ex('def myfunc(a=1,b=2): return a+b')
355 ip.ex('def myfunc(a=1,b=2): return a+b')
356 s, matches = c.complete(None, 'myfunc(1,b')
356 s, matches = c.complete(None, 'myfunc(1,b')
357 nt.assert_in('b=', matches)
357 nt.assert_in('b=', matches)
358 # Simulate completing with cursor right after b (pos==10):
358 # Simulate completing with cursor right after b (pos==10):
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 nt.assert_in('b=', matches)
360 nt.assert_in('b=', matches)
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 nt.assert_in('b=', matches)
362 nt.assert_in('b=', matches)
363 #builtin function
363 #builtin function
364 s, matches = c.complete(None, 'min(k, k')
364 s, matches = c.complete(None, 'min(k, k')
365 nt.assert_in('key=', matches)
365 nt.assert_in('key=', matches)
366
366
367
367
368 def test_default_arguments_from_docstring():
368 def test_default_arguments_from_docstring():
369 ip = get_ipython()
369 ip = get_ipython()
370 c = ip.Completer
370 c = ip.Completer
371 kwd = c._default_arguments_from_docstring(
371 kwd = c._default_arguments_from_docstring(
372 'min(iterable[, key=func]) -> value')
372 'min(iterable[, key=func]) -> value')
373 nt.assert_equal(kwd, ['key'])
373 nt.assert_equal(kwd, ['key'])
374 #with cython type etc
374 #with cython type etc
375 kwd = c._default_arguments_from_docstring(
375 kwd = c._default_arguments_from_docstring(
376 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
376 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
377 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
377 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
378 #white spaces
378 #white spaces
379 kwd = c._default_arguments_from_docstring(
379 kwd = c._default_arguments_from_docstring(
380 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
380 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
381 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
381 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
382
382
383 def test_line_magics():
383 def test_line_magics():
384 ip = get_ipython()
384 ip = get_ipython()
385 c = ip.Completer
385 c = ip.Completer
386 s, matches = c.complete(None, 'lsmag')
386 s, matches = c.complete(None, 'lsmag')
387 nt.assert_in('%lsmagic', matches)
387 nt.assert_in('%lsmagic', matches)
388 s, matches = c.complete(None, '%lsmag')
388 s, matches = c.complete(None, '%lsmag')
389 nt.assert_in('%lsmagic', matches)
389 nt.assert_in('%lsmagic', matches)
390
390
391
391
392 def test_cell_magics():
392 def test_cell_magics():
393 from IPython.core.magic import register_cell_magic
393 from IPython.core.magic import register_cell_magic
394
394
395 @register_cell_magic
395 @register_cell_magic
396 def _foo_cellm(line, cell):
396 def _foo_cellm(line, cell):
397 pass
397 pass
398
398
399 ip = get_ipython()
399 ip = get_ipython()
400 c = ip.Completer
400 c = ip.Completer
401
401
402 s, matches = c.complete(None, '_foo_ce')
402 s, matches = c.complete(None, '_foo_ce')
403 nt.assert_in('%%_foo_cellm', matches)
403 nt.assert_in('%%_foo_cellm', matches)
404 s, matches = c.complete(None, '%%_foo_ce')
404 s, matches = c.complete(None, '%%_foo_ce')
405 nt.assert_in('%%_foo_cellm', matches)
405 nt.assert_in('%%_foo_cellm', matches)
406
406
407
407
408 def test_line_cell_magics():
408 def test_line_cell_magics():
409 from IPython.core.magic import register_line_cell_magic
409 from IPython.core.magic import register_line_cell_magic
410
410
411 @register_line_cell_magic
411 @register_line_cell_magic
412 def _bar_cellm(line, cell):
412 def _bar_cellm(line, cell):
413 pass
413 pass
414
414
415 ip = get_ipython()
415 ip = get_ipython()
416 c = ip.Completer
416 c = ip.Completer
417
417
418 # The policy here is trickier, see comments in completion code. The
418 # The policy here is trickier, see comments in completion code. The
419 # returned values depend on whether the user passes %% or not explicitly,
419 # 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
420 # and this will show a difference if the same name is both a line and cell
421 # magic.
421 # magic.
422 s, matches = c.complete(None, '_bar_ce')
422 s, matches = c.complete(None, '_bar_ce')
423 nt.assert_in('%_bar_cellm', matches)
423 nt.assert_in('%_bar_cellm', matches)
424 nt.assert_in('%%_bar_cellm', matches)
424 nt.assert_in('%%_bar_cellm', matches)
425 s, matches = c.complete(None, '%_bar_ce')
425 s, matches = c.complete(None, '%_bar_ce')
426 nt.assert_in('%_bar_cellm', matches)
426 nt.assert_in('%_bar_cellm', matches)
427 nt.assert_in('%%_bar_cellm', matches)
427 nt.assert_in('%%_bar_cellm', matches)
428 s, matches = c.complete(None, '%%_bar_ce')
428 s, matches = c.complete(None, '%%_bar_ce')
429 nt.assert_not_in('%_bar_cellm', matches)
429 nt.assert_not_in('%_bar_cellm', matches)
430 nt.assert_in('%%_bar_cellm', matches)
430 nt.assert_in('%%_bar_cellm', matches)
431
431
432
432
433 def test_magic_completion_order():
433 def test_magic_completion_order():
434
434
435 ip = get_ipython()
435 ip = get_ipython()
436 c = ip.Completer
436 c = ip.Completer
437
437
438 # Test ordering of magics and non-magics with the same name
438 # Test ordering of magics and non-magics with the same name
439 # We want the non-magic first
439 # We want the non-magic first
440
440
441 # Before importing matplotlib, there should only be one option:
441 # Before importing matplotlib, there should only be one option:
442
442
443 text, matches = c.complete('mat')
443 text, matches = c.complete('mat')
444 nt.assert_equal(matches, ["%matplotlib"])
444 nt.assert_equal(matches, ["%matplotlib"])
445
445
446
446
447 ip.run_cell("matplotlib = 1") # introduce name into namespace
447 ip.run_cell("matplotlib = 1") # introduce name into namespace
448
448
449 # After the import, there should be two options, ordered like this:
449 # After the import, there should be two options, ordered like this:
450 text, matches = c.complete('mat')
450 text, matches = c.complete('mat')
451 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
451 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
452
452
453
453
454 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
454 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
455
455
456 # Order of user variable and line and cell magics with same name:
456 # Order of user variable and line and cell magics with same name:
457 text, matches = c.complete('timeit')
457 text, matches = c.complete('timeit')
458 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
458 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
459
459
460
460
461 def test_dict_key_completion_string():
461 def test_dict_key_completion_string():
462 """Test dictionary key completion for string keys"""
462 """Test dictionary key completion for string keys"""
463 ip = get_ipython()
463 ip = get_ipython()
464 complete = ip.Completer.complete
464 complete = ip.Completer.complete
465
465
466 ip.user_ns['d'] = {'abc': None}
466 ip.user_ns['d'] = {'abc': None}
467
467
468 # check completion at different stages
468 # check completion at different stages
469 _, matches = complete(line_buffer="d[")
469 _, matches = complete(line_buffer="d[")
470 nt.assert_in("'abc'", matches)
470 nt.assert_in("'abc'", matches)
471 nt.assert_not_in("'abc']", matches)
471 nt.assert_not_in("'abc']", matches)
472
472
473 _, matches = complete(line_buffer="d['")
473 _, matches = complete(line_buffer="d['")
474 nt.assert_in("abc", matches)
474 nt.assert_in("abc", matches)
475 nt.assert_not_in("abc']", matches)
475 nt.assert_not_in("abc']", matches)
476
476
477 _, matches = complete(line_buffer="d['a")
477 _, matches = complete(line_buffer="d['a")
478 nt.assert_in("abc", matches)
478 nt.assert_in("abc", matches)
479 nt.assert_not_in("abc']", matches)
479 nt.assert_not_in("abc']", matches)
480
480
481 # check use of different quoting
481 # check use of different quoting
482 _, matches = complete(line_buffer="d[\"")
482 _, matches = complete(line_buffer="d[\"")
483 nt.assert_in("abc", matches)
483 nt.assert_in("abc", matches)
484 nt.assert_not_in('abc\"]', matches)
484 nt.assert_not_in('abc\"]', matches)
485
485
486 _, matches = complete(line_buffer="d[\"a")
486 _, matches = complete(line_buffer="d[\"a")
487 nt.assert_in("abc", matches)
487 nt.assert_in("abc", matches)
488 nt.assert_not_in('abc\"]', matches)
488 nt.assert_not_in('abc\"]', matches)
489
489
490 # check sensitivity to following context
490 # check sensitivity to following context
491 _, matches = complete(line_buffer="d[]", cursor_pos=2)
491 _, matches = complete(line_buffer="d[]", cursor_pos=2)
492 nt.assert_in("'abc'", matches)
492 nt.assert_in("'abc'", matches)
493
493
494 _, matches = complete(line_buffer="d['']", cursor_pos=3)
494 _, matches = complete(line_buffer="d['']", cursor_pos=3)
495 nt.assert_in("abc", matches)
495 nt.assert_in("abc", matches)
496 nt.assert_not_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
498
499 # check multiple solutions are correctly returned and that noise is not
499 # check multiple solutions are correctly returned and that noise is not
500 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
500 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
501 5: None}
501 5: None}
502
502
503 _, matches = complete(line_buffer="d['a")
503 _, matches = complete(line_buffer="d['a")
504 nt.assert_in("abc", matches)
504 nt.assert_in("abc", matches)
505 nt.assert_in("abd", matches)
505 nt.assert_in("abd", matches)
506 nt.assert_not_in("bad", matches)
506 nt.assert_not_in("bad", matches)
507 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
507 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
508
508
509 # check escaping and whitespace
509 # check escaping and whitespace
510 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
510 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
511 _, matches = complete(line_buffer="d['a")
511 _, matches = complete(line_buffer="d['a")
512 nt.assert_in("a\\nb", matches)
512 nt.assert_in("a\\nb", matches)
513 nt.assert_in("a\\'b", 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 word", matches)
515 nt.assert_in("a word", matches)
516 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
516 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
517
517
518 # - can complete on non-initial word of the string
518 # - can complete on non-initial word of the string
519 _, matches = complete(line_buffer="d['a w")
519 _, matches = complete(line_buffer="d['a w")
520 nt.assert_in("word", matches)
520 nt.assert_in("word", matches)
521
521
522 # - understands quote escaping
522 # - understands quote escaping
523 _, matches = complete(line_buffer="d['a\\'")
523 _, matches = complete(line_buffer="d['a\\'")
524 nt.assert_in("b", matches)
524 nt.assert_in("b", matches)
525
525
526 # - default quoting should work like repr
526 # - default quoting should work like repr
527 _, matches = complete(line_buffer="d[")
527 _, matches = complete(line_buffer="d[")
528 nt.assert_in("\"a'b\"", matches)
528 nt.assert_in("\"a'b\"", matches)
529
529
530 # - when opening quote with ", possible to match with unescaped apostrophe
530 # - when opening quote with ", possible to match with unescaped apostrophe
531 _, matches = complete(line_buffer="d[\"a'")
531 _, matches = complete(line_buffer="d[\"a'")
532 nt.assert_in("b", matches)
532 nt.assert_in("b", matches)
533
533
534 # need to not split at delims that readline won't split at
534 # need to not split at delims that readline won't split at
535 if '-' not in ip.Completer.splitter.delims:
535 if '-' not in ip.Completer.splitter.delims:
536 ip.user_ns['d'] = {'before-after': None}
536 ip.user_ns['d'] = {'before-after': None}
537 _, matches = complete(line_buffer="d['before-af")
537 _, matches = complete(line_buffer="d['before-af")
538 nt.assert_in('before-after', matches)
538 nt.assert_in('before-after', matches)
539
539
540 def test_dict_key_completion_contexts():
540 def test_dict_key_completion_contexts():
541 """Test expression contexts in which dict key completion occurs"""
541 """Test expression contexts in which dict key completion occurs"""
542 ip = get_ipython()
542 ip = get_ipython()
543 complete = ip.Completer.complete
543 complete = ip.Completer.complete
544 d = {'abc': None}
544 d = {'abc': None}
545 ip.user_ns['d'] = d
545 ip.user_ns['d'] = d
546
546
547 class C:
547 class C:
548 data = d
548 data = d
549 ip.user_ns['C'] = C
549 ip.user_ns['C'] = C
550 ip.user_ns['get'] = lambda: d
550 ip.user_ns['get'] = lambda: d
551
551
552 def assert_no_completion(**kwargs):
552 def assert_no_completion(**kwargs):
553 _, matches = complete(**kwargs)
553 _, matches = complete(**kwargs)
554 nt.assert_not_in('abc', matches)
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
559
560 def assert_completion(**kwargs):
560 def assert_completion(**kwargs):
561 _, matches = complete(**kwargs)
561 _, matches = complete(**kwargs)
562 nt.assert_in("'abc'", matches)
562 nt.assert_in("'abc'", matches)
563 nt.assert_not_in("'abc']", matches)
563 nt.assert_not_in("'abc']", matches)
564
564
565 # no completion after string closed, even if reopened
565 # no completion after string closed, even if reopened
566 assert_no_completion(line_buffer="d['a'")
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
570
571 # completion in non-trivial expressions
571 # completion in non-trivial expressions
572 assert_completion(line_buffer="+ d[")
572 assert_completion(line_buffer="+ d[")
573 assert_completion(line_buffer="(d[")
573 assert_completion(line_buffer="(d[")
574 assert_completion(line_buffer="C.data[")
574 assert_completion(line_buffer="C.data[")
575
575
576 # greedy flag
576 # greedy flag
577 def assert_completion(**kwargs):
577 def assert_completion(**kwargs):
578 _, matches = complete(**kwargs)
578 _, matches = complete(**kwargs)
579 nt.assert_in("get()['abc']", matches)
579 nt.assert_in("get()['abc']", matches)
580
580
581 assert_no_completion(line_buffer="get()[")
581 assert_no_completion(line_buffer="get()[")
582 with greedy_completion():
582 with greedy_completion():
583 assert_completion(line_buffer="get()[")
583 assert_completion(line_buffer="get()[")
584 assert_completion(line_buffer="get()['")
584 assert_completion(line_buffer="get()['")
585 assert_completion(line_buffer="get()['a")
585 assert_completion(line_buffer="get()['a")
586 assert_completion(line_buffer="get()['ab")
586 assert_completion(line_buffer="get()['ab")
587 assert_completion(line_buffer="get()['abc")
587 assert_completion(line_buffer="get()['abc")
588
588
589
589
590
590
591 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
591 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
592 def test_dict_key_completion_bytes():
592 def test_dict_key_completion_bytes():
593 """Test handling of bytes in dict key completion"""
593 """Test handling of bytes in dict key completion"""
594 ip = get_ipython()
594 ip = get_ipython()
595 complete = ip.Completer.complete
595 complete = ip.Completer.complete
596
596
597 ip.user_ns['d'] = {'abc': None, b'abd': None}
597 ip.user_ns['d'] = {'abc': None, b'abd': None}
598
598
599 _, matches = complete(line_buffer="d[")
599 _, matches = complete(line_buffer="d[")
600 nt.assert_in("'abc'", matches)
600 nt.assert_in("'abc'", matches)
601 nt.assert_in("b'abd'", matches)
601 nt.assert_in("b'abd'", matches)
602
602
603 if False: # not currently implemented
603 if False: # not currently implemented
604 _, matches = complete(line_buffer="d[b")
604 _, matches = complete(line_buffer="d[b")
605 nt.assert_in("b'abd'", matches)
605 nt.assert_in("b'abd'", matches)
606 nt.assert_not_in("b'abc'", matches)
606 nt.assert_not_in("b'abc'", matches)
607
607
608 _, matches = complete(line_buffer="d[b'")
608 _, matches = complete(line_buffer="d[b'")
609 nt.assert_in("abd", matches)
609 nt.assert_in("abd", matches)
610 nt.assert_not_in("abc", matches)
610 nt.assert_not_in("abc", matches)
611
611
612 _, matches = complete(line_buffer="d[B'")
612 _, matches = complete(line_buffer="d[B'")
613 nt.assert_in("abd", matches)
613 nt.assert_in("abd", matches)
614 nt.assert_not_in("abc", matches)
614 nt.assert_not_in("abc", matches)
615
615
616 _, matches = complete(line_buffer="d['")
616 _, matches = complete(line_buffer="d['")
617 nt.assert_in("abc", matches)
617 nt.assert_in("abc", matches)
618 nt.assert_not_in("abd", matches)
618 nt.assert_not_in("abd", matches)
619
619
620
620
621 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
621 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
622 def test_dict_key_completion_unicode_py2():
622 def test_dict_key_completion_unicode_py2():
623 """Test handling of unicode in dict key completion"""
623 """Test handling of unicode in dict key completion"""
624 ip = get_ipython()
624 ip = get_ipython()
625 complete = ip.Completer.complete
625 complete = ip.Completer.complete
626
626
627 ip.user_ns['d'] = {u'abc': None,
627 ip.user_ns['d'] = {u'abc': None,
628 u'a\u05d0b': None}
628 u'a\u05d0b': None}
629
629
630 _, matches = complete(line_buffer="d[")
630 _, matches = complete(line_buffer="d[")
631 nt.assert_in("u'abc'", matches)
631 nt.assert_in("u'abc'", matches)
632 nt.assert_in("u'a\\u05d0b'", matches)
632 nt.assert_in("u'a\\u05d0b'", matches)
633
633
634 _, matches = complete(line_buffer="d['a")
634 _, matches = complete(line_buffer="d['a")
635 nt.assert_in("abc", matches)
635 nt.assert_in("abc", matches)
636 nt.assert_not_in("a\\u05d0b", matches)
636 nt.assert_not_in("a\\u05d0b", matches)
637
637
638 _, matches = complete(line_buffer="d[u'a")
638 _, matches = complete(line_buffer="d[u'a")
639 nt.assert_in("abc", matches)
639 nt.assert_in("abc", matches)
640 nt.assert_in("a\\u05d0b", matches)
640 nt.assert_in("a\\u05d0b", matches)
641
641
642 _, matches = complete(line_buffer="d[U'a")
642 _, matches = complete(line_buffer="d[U'a")
643 nt.assert_in("abc", matches)
643 nt.assert_in("abc", matches)
644 nt.assert_in("a\\u05d0b", matches)
644 nt.assert_in("a\\u05d0b", matches)
645
645
646 # query using escape
646 # query using escape
647 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
647 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
648 nt.assert_in("u05d0b", matches) # tokenized after \\
648 nt.assert_in("u05d0b", matches) # tokenized after \\
649
649
650 # query using character
650 # query using character
651 _, matches = complete(line_buffer=u"d[u'a\u05d0")
651 _, matches = complete(line_buffer=u"d[u'a\u05d0")
652 nt.assert_in(u"a\u05d0b", matches)
652 nt.assert_in(u"a\u05d0b", matches)
653
653
654 with greedy_completion():
654 with greedy_completion():
655 _, matches = complete(line_buffer="d[")
655 _, matches = complete(line_buffer="d[")
656 nt.assert_in("d[u'abc']", matches)
656 nt.assert_in("d[u'abc']", matches)
657 nt.assert_in("d[u'a\\u05d0b']", matches)
657 nt.assert_in("d[u'a\\u05d0b']", matches)
658
658
659 _, matches = complete(line_buffer="d['a")
659 _, matches = complete(line_buffer="d['a")
660 nt.assert_in("d['abc']", matches)
660 nt.assert_in("d['abc']", matches)
661 nt.assert_not_in("d[u'a\\u05d0b']", matches)
661 nt.assert_not_in("d[u'a\\u05d0b']", matches)
662
662
663 _, matches = complete(line_buffer="d[u'a")
663 _, matches = complete(line_buffer="d[u'a")
664 nt.assert_in("d[u'abc']", matches)
664 nt.assert_in("d[u'abc']", matches)
665 nt.assert_in("d[u'a\\u05d0b']", matches)
665 nt.assert_in("d[u'a\\u05d0b']", matches)
666
666
667 _, matches = complete(line_buffer="d[U'a")
667 _, matches = complete(line_buffer="d[U'a")
668 nt.assert_in("d[U'abc']", matches)
668 nt.assert_in("d[U'abc']", matches)
669 nt.assert_in("d[U'a\\u05d0b']", matches)
669 nt.assert_in("d[U'a\\u05d0b']", matches)
670
670
671 # query using escape
671 # query using escape
672 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
672 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
673 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
673 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
674
674
675 # query using character
675 # query using character
676 _, matches = complete(line_buffer=u"d[u'a\u05d0")
676 _, matches = complete(line_buffer=u"d[u'a\u05d0")
677 nt.assert_in(u"d[u'a\u05d0b']", matches)
677 nt.assert_in(u"d[u'a\u05d0b']", matches)
678
678
679
679
680 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
680 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
681 def test_dict_key_completion_unicode_py3():
681 def test_dict_key_completion_unicode_py3():
682 """Test handling of unicode in dict key completion"""
682 """Test handling of unicode in dict key completion"""
683 ip = get_ipython()
683 ip = get_ipython()
684 complete = ip.Completer.complete
684 complete = ip.Completer.complete
685
685
686 ip.user_ns['d'] = {u'a\u05d0': None}
686 ip.user_ns['d'] = {u'a\u05d0': None}
687
687
688 # query using escape
688 # query using escape
689 _, matches = complete(line_buffer="d['a\\u05d0")
689 _, matches = complete(line_buffer="d['a\\u05d0")
690 nt.assert_in("u05d0", matches) # tokenized after \\
690 nt.assert_in("u05d0", matches) # tokenized after \\
691
691
692 # query using character
692 # query using character
693 _, matches = complete(line_buffer="d['a\u05d0")
693 _, matches = complete(line_buffer="d['a\u05d0")
694 nt.assert_in(u"a\u05d0", matches)
694 nt.assert_in(u"a\u05d0", matches)
695
695
696 with greedy_completion():
696 with greedy_completion():
697 # query using escape
697 # query using escape
698 _, matches = complete(line_buffer="d['a\\u05d0")
698 _, matches = complete(line_buffer="d['a\\u05d0")
699 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
699 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
700
700
701 # query using character
701 # query using character
702 _, matches = complete(line_buffer="d['a\u05d0")
702 _, matches = complete(line_buffer="d['a\u05d0")
703 nt.assert_in(u"d['a\u05d0']", matches)
703 nt.assert_in(u"d['a\u05d0']", matches)
704
704
705
705
706
706
707 @dec.skip_without('numpy')
707 @dec.skip_without('numpy')
708 def test_struct_array_key_completion():
708 def test_struct_array_key_completion():
709 """Test dict key completion applies to numpy struct arrays"""
709 """Test dict key completion applies to numpy struct arrays"""
710 import numpy
710 import numpy
711 ip = get_ipython()
711 ip = get_ipython()
712 complete = ip.Completer.complete
712 complete = ip.Completer.complete
713 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
713 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
714 _, matches = complete(line_buffer="d['")
714 _, matches = complete(line_buffer="d['")
715 nt.assert_in("hello", matches)
715 nt.assert_in("hello", matches)
716 nt.assert_in("world", matches)
716 nt.assert_in("world", matches)
717 # complete on the numpy struct itself
717 # complete on the numpy struct itself
718 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
718 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
719 ('my_data', '>f4', 5)])
719 ('my_data', '>f4', 5)])
720 x = numpy.zeros(2, dtype=dt)
720 x = numpy.zeros(2, dtype=dt)
721 ip.user_ns['d'] = x[1]
721 ip.user_ns['d'] = x[1]
722 _, matches = complete(line_buffer="d['")
722 _, matches = complete(line_buffer="d['")
723 nt.assert_in("my_head", matches)
723 nt.assert_in("my_head", matches)
724 nt.assert_in("my_data", matches)
724 nt.assert_in("my_data", matches)
725 # complete on a nested level
725 # complete on a nested level
726 with greedy_completion():
726 with greedy_completion():
727 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
727 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
728 _, matches = complete(line_buffer="d[1]['my_head']['")
728 _, matches = complete(line_buffer="d[1]['my_head']['")
729 nt.assert_true(any(["my_dt" in m for m in matches]))
729 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]))
730 nt.assert_true(any(["my_df" in m for m in matches]))
731
731
732
732
733 @dec.skip_without('pandas')
733 @dec.skip_without('pandas')
734 def test_dataframe_key_completion():
734 def test_dataframe_key_completion():
735 """Test dict key completion applies to pandas DataFrames"""
735 """Test dict key completion applies to pandas DataFrames"""
736 import pandas
736 import pandas
737 ip = get_ipython()
737 ip = get_ipython()
738 complete = ip.Completer.complete
738 complete = ip.Completer.complete
739 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
739 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
740 _, matches = complete(line_buffer="d['")
740 _, matches = complete(line_buffer="d['")
741 nt.assert_in("hello", matches)
741 nt.assert_in("hello", matches)
742 nt.assert_in("world", matches)
742 nt.assert_in("world", matches)
743
743
744
744
745 def test_dict_key_completion_invalids():
745 def test_dict_key_completion_invalids():
746 """Smoke test cases dict key completion can't handle"""
746 """Smoke test cases dict key completion can't handle"""
747 ip = get_ipython()
747 ip = get_ipython()
748 complete = ip.Completer.complete
748 complete = ip.Completer.complete
749
749
750 ip.user_ns['no_getitem'] = None
750 ip.user_ns['no_getitem'] = None
751 ip.user_ns['no_keys'] = []
751 ip.user_ns['no_keys'] = []
752 ip.user_ns['cant_call_keys'] = dict
752 ip.user_ns['cant_call_keys'] = dict
753 ip.user_ns['empty'] = {}
753 ip.user_ns['empty'] = {}
754 ip.user_ns['d'] = {'abc': 5}
754 ip.user_ns['d'] = {'abc': 5}
755
755
756 _, matches = complete(line_buffer="no_getitem['")
756 _, matches = complete(line_buffer="no_getitem['")
757 _, matches = complete(line_buffer="no_keys['")
757 _, matches = complete(line_buffer="no_keys['")
758 _, matches = complete(line_buffer="cant_call_keys['")
758 _, matches = complete(line_buffer="cant_call_keys['")
759 _, matches = complete(line_buffer="empty['")
759 _, matches = complete(line_buffer="empty['")
760 _, matches = complete(line_buffer="name_error['")
760 _, matches = complete(line_buffer="name_error['")
761 _, matches = complete(line_buffer="d['\\") # incomplete escape
761 _, matches = complete(line_buffer="d['\\") # incomplete escape
762
762
763 class KeyCompletable(object):
763 class KeyCompletable(object):
764 def __init__(self, things=()):
764 def __init__(self, things=()):
765 self.things = things
765 self.things = things
766
766
767 def _ipython_key_completions_(self):
767 def _ipython_key_completions_(self):
768 return list(self.things)
768 return list(self.things)
769
769
770 def test_object_key_completion():
770 def test_object_key_completion():
771 ip = get_ipython()
771 ip = get_ipython()
772 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
772 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
773
773
774 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
774 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
775 nt.assert_in('qwerty', matches)
775 nt.assert_in('qwerty', matches)
776 nt.assert_in('qwick', matches)
776 nt.assert_in('qwick', matches)
777
777
778
778
779 def test_aimport_module_completer():
779 def test_aimport_module_completer():
780 ip = get_ipython()
780 ip = get_ipython()
781 _, matches = ip.complete('i', '%aimport i')
781 _, matches = ip.complete('i', '%aimport i')
782 nt.assert_in('io', matches)
782 nt.assert_in('io', matches)
783 nt.assert_not_in('int', matches)
783 nt.assert_not_in('int', matches)
784
784
785 def test_nested_import_module_completer():
785 def test_nested_import_module_completer():
786 ip = get_ipython()
786 ip = get_ipython()
787 _, matches = ip.complete(None, 'import IPython.co', 17)
787 _, matches = ip.complete(None, 'import IPython.co', 17)
788 nt.assert_in('IPython.core', matches)
788 nt.assert_in('IPython.core', matches)
789 nt.assert_not_in('import IPython.core', matches)
789 nt.assert_not_in('import IPython.core', matches)
790 nt.assert_not_in('IPython.display', matches)
790 nt.assert_not_in('IPython.display', matches)
791
791
792 def test_import_module_completer():
792 def test_import_module_completer():
793 ip = get_ipython()
793 ip = get_ipython()
794 _, matches = ip.complete('i', 'import i')
794 _, matches = ip.complete('i', 'import i')
795 nt.assert_in('io', matches)
795 nt.assert_in('io', matches)
796 nt.assert_not_in('int', matches)
796 nt.assert_not_in('int', matches)
797
797
798 def test_from_module_completer():
798 def test_from_module_completer():
799 ip = get_ipython()
799 ip = get_ipython()
800 _, matches = ip.complete('B', 'from io import B', 16)
800 _, matches = ip.complete('B', 'from io import B', 16)
801 nt.assert_in('BytesIO', matches)
801 nt.assert_in('BytesIO', matches)
802 nt.assert_not_in('BaseException', matches)
802 nt.assert_not_in('BaseException', matches)
General Comments 0
You need to be logged in to leave comments. Login now