##// END OF EJS Templates
convert assert_equals to assert_equal
Srinivas Reddy Thatiparthy -
Show More
@@ -1,739 +1,739 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 def test_latex_completions():
135 def test_latex_completions():
136 from IPython.core.latex_symbols import latex_symbols
136 from IPython.core.latex_symbols import latex_symbols
137 import random
137 import random
138 ip = get_ipython()
138 ip = get_ipython()
139 # Test some random unicode symbols
139 # Test some random unicode symbols
140 keys = random.sample(latex_symbols.keys(), 10)
140 keys = random.sample(latex_symbols.keys(), 10)
141 for k in keys:
141 for k in keys:
142 text, matches = ip.complete(k)
142 text, matches = ip.complete(k)
143 nt.assert_equal(len(matches),1)
143 nt.assert_equal(len(matches),1)
144 nt.assert_equal(text, k)
144 nt.assert_equal(text, k)
145 nt.assert_equal(matches[0], latex_symbols[k])
145 nt.assert_equal(matches[0], latex_symbols[k])
146 # Test a more complex line
146 # Test a more complex line
147 text, matches = ip.complete(u'print(\\alpha')
147 text, matches = ip.complete(u'print(\\alpha')
148 nt.assert_equals(text, u'\\alpha')
148 nt.assert_equal(text, u'\\alpha')
149 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
149 nt.assert_equal(matches[0], latex_symbols['\\alpha'])
150 # Test multiple matching latex symbols
150 # Test multiple matching latex symbols
151 text, matches = ip.complete(u'\\al')
151 text, matches = ip.complete(u'\\al')
152 nt.assert_in('\\alpha', matches)
152 nt.assert_in('\\alpha', matches)
153 nt.assert_in('\\aleph', matches)
153 nt.assert_in('\\aleph', matches)
154
154
155
155
156
156
157
157
158 def test_back_latex_completion():
158 def test_back_latex_completion():
159 ip = get_ipython()
159 ip = get_ipython()
160
160
161 # do not return more than 1 matches fro \beta, only the latex one.
161 # do not return more than 1 matches fro \beta, only the latex one.
162 name, matches = ip.complete('\\Ξ²')
162 name, matches = ip.complete('\\Ξ²')
163 nt.assert_equal(len(matches), 1)
163 nt.assert_equal(len(matches), 1)
164 nt.assert_equal(matches[0], '\\beta')
164 nt.assert_equal(matches[0], '\\beta')
165
165
166 def test_back_unicode_completion():
166 def test_back_unicode_completion():
167 ip = get_ipython()
167 ip = get_ipython()
168
168
169 name, matches = ip.complete('\\β…€')
169 name, matches = ip.complete('\\β…€')
170 nt.assert_equal(len(matches), 1)
170 nt.assert_equal(len(matches), 1)
171 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
171 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
172
172
173
173
174 def test_forward_unicode_completion():
174 def test_forward_unicode_completion():
175 ip = get_ipython()
175 ip = get_ipython()
176
176
177 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
177 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
178 nt.assert_equal(len(matches), 1)
178 nt.assert_equal(len(matches), 1)
179 nt.assert_equal(matches[0], 'β…€')
179 nt.assert_equal(matches[0], 'β…€')
180
180
181 @dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
181 @dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
182 def test_no_ascii_back_completion():
182 def test_no_ascii_back_completion():
183 ip = get_ipython()
183 ip = get_ipython()
184 with TemporaryWorkingDirectory(): # Avoid any filename completions
184 with TemporaryWorkingDirectory(): # Avoid any filename completions
185 # single ascii letter that don't have yet completions
185 # single ascii letter that don't have yet completions
186 for letter in 'jJ' :
186 for letter in 'jJ' :
187 name, matches = ip.complete('\\'+letter)
187 name, matches = ip.complete('\\'+letter)
188 nt.assert_equal(matches, [])
188 nt.assert_equal(matches, [])
189
189
190
190
191
191
192
192
193 class CompletionSplitterTestCase(unittest.TestCase):
193 class CompletionSplitterTestCase(unittest.TestCase):
194 def setUp(self):
194 def setUp(self):
195 self.sp = completer.CompletionSplitter()
195 self.sp = completer.CompletionSplitter()
196
196
197 def test_delim_setting(self):
197 def test_delim_setting(self):
198 self.sp.delims = ' '
198 self.sp.delims = ' '
199 nt.assert_equal(self.sp.delims, ' ')
199 nt.assert_equal(self.sp.delims, ' ')
200 nt.assert_equal(self.sp._delim_expr, '[\ ]')
200 nt.assert_equal(self.sp._delim_expr, '[\ ]')
201
201
202 def test_spaces(self):
202 def test_spaces(self):
203 """Test with only spaces as split chars."""
203 """Test with only spaces as split chars."""
204 self.sp.delims = ' '
204 self.sp.delims = ' '
205 t = [('foo', '', 'foo'),
205 t = [('foo', '', 'foo'),
206 ('run foo', '', 'foo'),
206 ('run foo', '', 'foo'),
207 ('run foo', 'bar', 'foo'),
207 ('run foo', 'bar', 'foo'),
208 ]
208 ]
209 check_line_split(self.sp, t)
209 check_line_split(self.sp, t)
210
210
211
211
212 def test_has_open_quotes1():
212 def test_has_open_quotes1():
213 for s in ["'", "'''", "'hi' '"]:
213 for s in ["'", "'''", "'hi' '"]:
214 nt.assert_equal(completer.has_open_quotes(s), "'")
214 nt.assert_equal(completer.has_open_quotes(s), "'")
215
215
216
216
217 def test_has_open_quotes2():
217 def test_has_open_quotes2():
218 for s in ['"', '"""', '"hi" "']:
218 for s in ['"', '"""', '"hi" "']:
219 nt.assert_equal(completer.has_open_quotes(s), '"')
219 nt.assert_equal(completer.has_open_quotes(s), '"')
220
220
221
221
222 def test_has_open_quotes3():
222 def test_has_open_quotes3():
223 for s in ["''", "''' '''", "'hi' 'ipython'"]:
223 for s in ["''", "''' '''", "'hi' 'ipython'"]:
224 nt.assert_false(completer.has_open_quotes(s))
224 nt.assert_false(completer.has_open_quotes(s))
225
225
226
226
227 def test_has_open_quotes4():
227 def test_has_open_quotes4():
228 for s in ['""', '""" """', '"hi" "ipython"']:
228 for s in ['""', '""" """', '"hi" "ipython"']:
229 nt.assert_false(completer.has_open_quotes(s))
229 nt.assert_false(completer.has_open_quotes(s))
230
230
231
231
232 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
232 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
233 def test_abspath_file_completions():
233 def test_abspath_file_completions():
234 ip = get_ipython()
234 ip = get_ipython()
235 with TemporaryDirectory() as tmpdir:
235 with TemporaryDirectory() as tmpdir:
236 prefix = os.path.join(tmpdir, 'foo')
236 prefix = os.path.join(tmpdir, 'foo')
237 suffixes = ['1', '2']
237 suffixes = ['1', '2']
238 names = [prefix+s for s in suffixes]
238 names = [prefix+s for s in suffixes]
239 for n in names:
239 for n in names:
240 open(n, 'w').close()
240 open(n, 'w').close()
241
241
242 # Check simple completion
242 # Check simple completion
243 c = ip.complete(prefix)[1]
243 c = ip.complete(prefix)[1]
244 nt.assert_equal(c, names)
244 nt.assert_equal(c, names)
245
245
246 # Now check with a function call
246 # Now check with a function call
247 cmd = 'a = f("%s' % prefix
247 cmd = 'a = f("%s' % prefix
248 c = ip.complete(prefix, cmd)[1]
248 c = ip.complete(prefix, cmd)[1]
249 comp = [prefix+s for s in suffixes]
249 comp = [prefix+s for s in suffixes]
250 nt.assert_equal(c, comp)
250 nt.assert_equal(c, comp)
251
251
252
252
253 def test_local_file_completions():
253 def test_local_file_completions():
254 ip = get_ipython()
254 ip = get_ipython()
255 with TemporaryWorkingDirectory():
255 with TemporaryWorkingDirectory():
256 prefix = './foo'
256 prefix = './foo'
257 suffixes = ['1', '2']
257 suffixes = ['1', '2']
258 names = [prefix+s for s in suffixes]
258 names = [prefix+s for s in suffixes]
259 for n in names:
259 for n in names:
260 open(n, 'w').close()
260 open(n, 'w').close()
261
261
262 # Check simple completion
262 # Check simple completion
263 c = ip.complete(prefix)[1]
263 c = ip.complete(prefix)[1]
264 nt.assert_equal(c, names)
264 nt.assert_equal(c, names)
265
265
266 # Now check with a function call
266 # Now check with a function call
267 cmd = 'a = f("%s' % prefix
267 cmd = 'a = f("%s' % prefix
268 c = ip.complete(prefix, cmd)[1]
268 c = ip.complete(prefix, cmd)[1]
269 comp = set(prefix+s for s in suffixes)
269 comp = set(prefix+s for s in suffixes)
270 nt.assert_true(comp.issubset(set(c)))
270 nt.assert_true(comp.issubset(set(c)))
271
271
272
272
273 def test_greedy_completions():
273 def test_greedy_completions():
274 ip = get_ipython()
274 ip = get_ipython()
275 ip.ex('a=list(range(5))')
275 ip.ex('a=list(range(5))')
276 _,c = ip.complete('.',line='a[0].')
276 _,c = ip.complete('.',line='a[0].')
277 nt.assert_false('.real' in c,
277 nt.assert_false('.real' in c,
278 "Shouldn't have completed on a[0]: %s"%c)
278 "Shouldn't have completed on a[0]: %s"%c)
279 with greedy_completion():
279 with greedy_completion():
280 def _(line, cursor_pos, expect, message):
280 def _(line, cursor_pos, expect, message):
281 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
281 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
282 nt.assert_in(expect, c, message%c)
282 nt.assert_in(expect, c, message%c)
283
283
284 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
284 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
285 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
285 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
286
286
287 if sys.version_info > (3,4):
287 if sys.version_info > (3,4):
288 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
288 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
289
289
290
290
291
291
292 def test_omit__names():
292 def test_omit__names():
293 # also happens to test IPCompleter as a configurable
293 # also happens to test IPCompleter as a configurable
294 ip = get_ipython()
294 ip = get_ipython()
295 ip._hidden_attr = 1
295 ip._hidden_attr = 1
296 ip._x = {}
296 ip._x = {}
297 c = ip.Completer
297 c = ip.Completer
298 ip.ex('ip=get_ipython()')
298 ip.ex('ip=get_ipython()')
299 cfg = Config()
299 cfg = Config()
300 cfg.IPCompleter.omit__names = 0
300 cfg.IPCompleter.omit__names = 0
301 c.update_config(cfg)
301 c.update_config(cfg)
302 s,matches = c.complete('ip.')
302 s,matches = c.complete('ip.')
303 nt.assert_in('ip.__str__', matches)
303 nt.assert_in('ip.__str__', matches)
304 nt.assert_in('ip._hidden_attr', matches)
304 nt.assert_in('ip._hidden_attr', matches)
305 cfg = Config()
305 cfg = Config()
306 cfg.IPCompleter.omit__names = 1
306 cfg.IPCompleter.omit__names = 1
307 c.update_config(cfg)
307 c.update_config(cfg)
308 s,matches = c.complete('ip.')
308 s,matches = c.complete('ip.')
309 nt.assert_not_in('ip.__str__', matches)
309 nt.assert_not_in('ip.__str__', matches)
310 nt.assert_in('ip._hidden_attr', matches)
310 nt.assert_in('ip._hidden_attr', matches)
311 cfg = Config()
311 cfg = Config()
312 cfg.IPCompleter.omit__names = 2
312 cfg.IPCompleter.omit__names = 2
313 c.update_config(cfg)
313 c.update_config(cfg)
314 s,matches = c.complete('ip.')
314 s,matches = c.complete('ip.')
315 nt.assert_not_in('ip.__str__', matches)
315 nt.assert_not_in('ip.__str__', matches)
316 nt.assert_not_in('ip._hidden_attr', matches)
316 nt.assert_not_in('ip._hidden_attr', matches)
317 s,matches = c.complete('ip._x.')
317 s,matches = c.complete('ip._x.')
318 nt.assert_in('ip._x.keys', matches)
318 nt.assert_in('ip._x.keys', matches)
319 del ip._hidden_attr
319 del ip._hidden_attr
320
320
321
321
322 def test_limit_to__all__False_ok():
322 def test_limit_to__all__False_ok():
323 ip = get_ipython()
323 ip = get_ipython()
324 c = ip.Completer
324 c = ip.Completer
325 ip.ex('class D: x=24')
325 ip.ex('class D: x=24')
326 ip.ex('d=D()')
326 ip.ex('d=D()')
327 cfg = Config()
327 cfg = Config()
328 cfg.IPCompleter.limit_to__all__ = False
328 cfg.IPCompleter.limit_to__all__ = False
329 c.update_config(cfg)
329 c.update_config(cfg)
330 s, matches = c.complete('d.')
330 s, matches = c.complete('d.')
331 nt.assert_in('d.x', matches)
331 nt.assert_in('d.x', matches)
332
332
333
333
334 def test_get__all__entries_ok():
334 def test_get__all__entries_ok():
335 class A(object):
335 class A(object):
336 __all__ = ['x', 1]
336 __all__ = ['x', 1]
337 words = completer.get__all__entries(A())
337 words = completer.get__all__entries(A())
338 nt.assert_equal(words, ['x'])
338 nt.assert_equal(words, ['x'])
339
339
340
340
341 def test_get__all__entries_no__all__ok():
341 def test_get__all__entries_no__all__ok():
342 class A(object):
342 class A(object):
343 pass
343 pass
344 words = completer.get__all__entries(A())
344 words = completer.get__all__entries(A())
345 nt.assert_equal(words, [])
345 nt.assert_equal(words, [])
346
346
347
347
348 def test_func_kw_completions():
348 def test_func_kw_completions():
349 ip = get_ipython()
349 ip = get_ipython()
350 c = ip.Completer
350 c = ip.Completer
351 ip.ex('def myfunc(a=1,b=2): return a+b')
351 ip.ex('def myfunc(a=1,b=2): return a+b')
352 s, matches = c.complete(None, 'myfunc(1,b')
352 s, matches = c.complete(None, 'myfunc(1,b')
353 nt.assert_in('b=', matches)
353 nt.assert_in('b=', matches)
354 # Simulate completing with cursor right after b (pos==10):
354 # Simulate completing with cursor right after b (pos==10):
355 s, matches = c.complete(None, 'myfunc(1,b)', 10)
355 s, matches = c.complete(None, 'myfunc(1,b)', 10)
356 nt.assert_in('b=', matches)
356 nt.assert_in('b=', matches)
357 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
357 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
358 nt.assert_in('b=', matches)
358 nt.assert_in('b=', matches)
359 #builtin function
359 #builtin function
360 s, matches = c.complete(None, 'min(k, k')
360 s, matches = c.complete(None, 'min(k, k')
361 nt.assert_in('key=', matches)
361 nt.assert_in('key=', matches)
362
362
363
363
364 def test_default_arguments_from_docstring():
364 def test_default_arguments_from_docstring():
365 ip = get_ipython()
365 ip = get_ipython()
366 c = ip.Completer
366 c = ip.Completer
367 kwd = c._default_arguments_from_docstring(
367 kwd = c._default_arguments_from_docstring(
368 'min(iterable[, key=func]) -> value')
368 'min(iterable[, key=func]) -> value')
369 nt.assert_equal(kwd, ['key'])
369 nt.assert_equal(kwd, ['key'])
370 #with cython type etc
370 #with cython type etc
371 kwd = c._default_arguments_from_docstring(
371 kwd = c._default_arguments_from_docstring(
372 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
372 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
373 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
373 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
374 #white spaces
374 #white spaces
375 kwd = c._default_arguments_from_docstring(
375 kwd = c._default_arguments_from_docstring(
376 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
376 '\n 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
378
379 def test_line_magics():
379 def test_line_magics():
380 ip = get_ipython()
380 ip = get_ipython()
381 c = ip.Completer
381 c = ip.Completer
382 s, matches = c.complete(None, 'lsmag')
382 s, matches = c.complete(None, 'lsmag')
383 nt.assert_in('%lsmagic', matches)
383 nt.assert_in('%lsmagic', matches)
384 s, matches = c.complete(None, '%lsmag')
384 s, matches = c.complete(None, '%lsmag')
385 nt.assert_in('%lsmagic', matches)
385 nt.assert_in('%lsmagic', matches)
386
386
387
387
388 def test_cell_magics():
388 def test_cell_magics():
389 from IPython.core.magic import register_cell_magic
389 from IPython.core.magic import register_cell_magic
390
390
391 @register_cell_magic
391 @register_cell_magic
392 def _foo_cellm(line, cell):
392 def _foo_cellm(line, cell):
393 pass
393 pass
394
394
395 ip = get_ipython()
395 ip = get_ipython()
396 c = ip.Completer
396 c = ip.Completer
397
397
398 s, matches = c.complete(None, '_foo_ce')
398 s, matches = c.complete(None, '_foo_ce')
399 nt.assert_in('%%_foo_cellm', matches)
399 nt.assert_in('%%_foo_cellm', matches)
400 s, matches = c.complete(None, '%%_foo_ce')
400 s, matches = c.complete(None, '%%_foo_ce')
401 nt.assert_in('%%_foo_cellm', matches)
401 nt.assert_in('%%_foo_cellm', matches)
402
402
403
403
404 def test_line_cell_magics():
404 def test_line_cell_magics():
405 from IPython.core.magic import register_line_cell_magic
405 from IPython.core.magic import register_line_cell_magic
406
406
407 @register_line_cell_magic
407 @register_line_cell_magic
408 def _bar_cellm(line, cell):
408 def _bar_cellm(line, cell):
409 pass
409 pass
410
410
411 ip = get_ipython()
411 ip = get_ipython()
412 c = ip.Completer
412 c = ip.Completer
413
413
414 # The policy here is trickier, see comments in completion code. The
414 # The policy here is trickier, see comments in completion code. The
415 # returned values depend on whether the user passes %% or not explicitly,
415 # returned values depend on whether the user passes %% or not explicitly,
416 # and this will show a difference if the same name is both a line and cell
416 # and this will show a difference if the same name is both a line and cell
417 # magic.
417 # magic.
418 s, matches = c.complete(None, '_bar_ce')
418 s, matches = c.complete(None, '_bar_ce')
419 nt.assert_in('%_bar_cellm', matches)
419 nt.assert_in('%_bar_cellm', matches)
420 nt.assert_in('%%_bar_cellm', matches)
420 nt.assert_in('%%_bar_cellm', matches)
421 s, matches = c.complete(None, '%_bar_ce')
421 s, matches = c.complete(None, '%_bar_ce')
422 nt.assert_in('%_bar_cellm', matches)
422 nt.assert_in('%_bar_cellm', matches)
423 nt.assert_in('%%_bar_cellm', matches)
423 nt.assert_in('%%_bar_cellm', matches)
424 s, matches = c.complete(None, '%%_bar_ce')
424 s, matches = c.complete(None, '%%_bar_ce')
425 nt.assert_not_in('%_bar_cellm', matches)
425 nt.assert_not_in('%_bar_cellm', matches)
426 nt.assert_in('%%_bar_cellm', matches)
426 nt.assert_in('%%_bar_cellm', matches)
427
427
428
428
429 def test_magic_completion_order():
429 def test_magic_completion_order():
430
430
431 ip = get_ipython()
431 ip = get_ipython()
432 c = ip.Completer
432 c = ip.Completer
433
433
434 # Test ordering of magics and non-magics with the same name
434 # Test ordering of magics and non-magics with the same name
435 # We want the non-magic first
435 # We want the non-magic first
436
436
437 # Before importing matplotlib, there should only be one option:
437 # Before importing matplotlib, there should only be one option:
438
438
439 text, matches = c.complete('mat')
439 text, matches = c.complete('mat')
440 nt.assert_equal(matches, ["%matplotlib"])
440 nt.assert_equal(matches, ["%matplotlib"])
441
441
442
442
443 ip.run_cell("matplotlib = 1") # introduce name into namespace
443 ip.run_cell("matplotlib = 1") # introduce name into namespace
444
444
445 # After the import, there should be two options, ordered like this:
445 # After the import, there should be two options, ordered like this:
446 text, matches = c.complete('mat')
446 text, matches = c.complete('mat')
447 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
447 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
448
448
449
449
450 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
450 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
451
451
452 # Order of user variable and line and cell magics with same name:
452 # Order of user variable and line and cell magics with same name:
453 text, matches = c.complete('timeit')
453 text, matches = c.complete('timeit')
454 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
454 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
455
455
456
456
457 def test_dict_key_completion_string():
457 def test_dict_key_completion_string():
458 """Test dictionary key completion for string keys"""
458 """Test dictionary key completion for string keys"""
459 ip = get_ipython()
459 ip = get_ipython()
460 complete = ip.Completer.complete
460 complete = ip.Completer.complete
461
461
462 ip.user_ns['d'] = {'abc': None}
462 ip.user_ns['d'] = {'abc': None}
463
463
464 # check completion at different stages
464 # check completion at different stages
465 _, matches = complete(line_buffer="d[")
465 _, matches = complete(line_buffer="d[")
466 nt.assert_in("'abc'", matches)
466 nt.assert_in("'abc'", matches)
467 nt.assert_not_in("'abc']", matches)
467 nt.assert_not_in("'abc']", matches)
468
468
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['a")
473 _, matches = complete(line_buffer="d['a")
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 # check use of different quoting
477 # check use of different quoting
478 _, matches = complete(line_buffer="d[\"")
478 _, matches = complete(line_buffer="d[\"")
479 nt.assert_in("abc", matches)
479 nt.assert_in("abc", matches)
480 nt.assert_not_in('abc\"]', matches)
480 nt.assert_not_in('abc\"]', matches)
481
481
482 _, matches = complete(line_buffer="d[\"a")
482 _, matches = complete(line_buffer="d[\"a")
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 # check sensitivity to following context
486 # check sensitivity to following context
487 _, matches = complete(line_buffer="d[]", cursor_pos=2)
487 _, matches = complete(line_buffer="d[]", cursor_pos=2)
488 nt.assert_in("'abc'", matches)
488 nt.assert_in("'abc'", matches)
489
489
490 _, matches = complete(line_buffer="d['']", cursor_pos=3)
490 _, matches = complete(line_buffer="d['']", cursor_pos=3)
491 nt.assert_in("abc", matches)
491 nt.assert_in("abc", matches)
492 nt.assert_not_in("abc'", matches)
492 nt.assert_not_in("abc'", matches)
493 nt.assert_not_in("abc']", matches)
493 nt.assert_not_in("abc']", matches)
494
494
495 # check multiple solutions are correctly returned and that noise is not
495 # check multiple solutions are correctly returned and that noise is not
496 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
496 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
497 5: None}
497 5: None}
498
498
499 _, matches = complete(line_buffer="d['a")
499 _, matches = complete(line_buffer="d['a")
500 nt.assert_in("abc", matches)
500 nt.assert_in("abc", matches)
501 nt.assert_in("abd", matches)
501 nt.assert_in("abd", matches)
502 nt.assert_not_in("bad", matches)
502 nt.assert_not_in("bad", matches)
503 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
503 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
504
504
505 # check escaping and whitespace
505 # check escaping and whitespace
506 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
506 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
507 _, matches = complete(line_buffer="d['a")
507 _, matches = complete(line_buffer="d['a")
508 nt.assert_in("a\\nb", matches)
508 nt.assert_in("a\\nb", matches)
509 nt.assert_in("a\\'b", matches)
509 nt.assert_in("a\\'b", matches)
510 nt.assert_in("a\"b", matches)
510 nt.assert_in("a\"b", matches)
511 nt.assert_in("a word", matches)
511 nt.assert_in("a word", matches)
512 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
512 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
513
513
514 # - can complete on non-initial word of the string
514 # - can complete on non-initial word of the string
515 _, matches = complete(line_buffer="d['a w")
515 _, matches = complete(line_buffer="d['a w")
516 nt.assert_in("word", matches)
516 nt.assert_in("word", matches)
517
517
518 # - understands quote escaping
518 # - understands quote escaping
519 _, matches = complete(line_buffer="d['a\\'")
519 _, matches = complete(line_buffer="d['a\\'")
520 nt.assert_in("b", matches)
520 nt.assert_in("b", matches)
521
521
522 # - default quoting should work like repr
522 # - default quoting should work like repr
523 _, matches = complete(line_buffer="d[")
523 _, matches = complete(line_buffer="d[")
524 nt.assert_in("\"a'b\"", matches)
524 nt.assert_in("\"a'b\"", matches)
525
525
526 # - when opening quote with ", possible to match with unescaped apostrophe
526 # - when opening quote with ", possible to match with unescaped apostrophe
527 _, matches = complete(line_buffer="d[\"a'")
527 _, matches = complete(line_buffer="d[\"a'")
528 nt.assert_in("b", matches)
528 nt.assert_in("b", matches)
529
529
530 # need to not split at delims that readline won't split at
530 # need to not split at delims that readline won't split at
531 if '-' not in ip.Completer.splitter.delims:
531 if '-' not in ip.Completer.splitter.delims:
532 ip.user_ns['d'] = {'before-after': None}
532 ip.user_ns['d'] = {'before-after': None}
533 _, matches = complete(line_buffer="d['before-af")
533 _, matches = complete(line_buffer="d['before-af")
534 nt.assert_in('before-after', matches)
534 nt.assert_in('before-after', matches)
535
535
536 def test_dict_key_completion_contexts():
536 def test_dict_key_completion_contexts():
537 """Test expression contexts in which dict key completion occurs"""
537 """Test expression contexts in which dict key completion occurs"""
538 ip = get_ipython()
538 ip = get_ipython()
539 complete = ip.Completer.complete
539 complete = ip.Completer.complete
540 d = {'abc': None}
540 d = {'abc': None}
541 ip.user_ns['d'] = d
541 ip.user_ns['d'] = d
542
542
543 class C:
543 class C:
544 data = d
544 data = d
545 ip.user_ns['C'] = C
545 ip.user_ns['C'] = C
546 ip.user_ns['get'] = lambda: d
546 ip.user_ns['get'] = lambda: d
547
547
548 def assert_no_completion(**kwargs):
548 def assert_no_completion(**kwargs):
549 _, matches = complete(**kwargs)
549 _, matches = complete(**kwargs)
550 nt.assert_not_in('abc', matches)
550 nt.assert_not_in('abc', matches)
551 nt.assert_not_in('abc\'', matches)
551 nt.assert_not_in('abc\'', matches)
552 nt.assert_not_in('abc\']', matches)
552 nt.assert_not_in('abc\']', matches)
553 nt.assert_not_in('\'abc\'', matches)
553 nt.assert_not_in('\'abc\'', matches)
554 nt.assert_not_in('\'abc\']', matches)
554 nt.assert_not_in('\'abc\']', matches)
555
555
556 def assert_completion(**kwargs):
556 def assert_completion(**kwargs):
557 _, matches = complete(**kwargs)
557 _, matches = complete(**kwargs)
558 nt.assert_in("'abc'", matches)
558 nt.assert_in("'abc'", matches)
559 nt.assert_not_in("'abc']", matches)
559 nt.assert_not_in("'abc']", matches)
560
560
561 # no completion after string closed, even if reopened
561 # no completion after string closed, even if reopened
562 assert_no_completion(line_buffer="d['a'")
562 assert_no_completion(line_buffer="d['a'")
563 assert_no_completion(line_buffer="d[\"a\"")
563 assert_no_completion(line_buffer="d[\"a\"")
564 assert_no_completion(line_buffer="d['a' + ")
564 assert_no_completion(line_buffer="d['a' + ")
565 assert_no_completion(line_buffer="d['a' + '")
565 assert_no_completion(line_buffer="d['a' + '")
566
566
567 # completion in non-trivial expressions
567 # completion in non-trivial expressions
568 assert_completion(line_buffer="+ d[")
568 assert_completion(line_buffer="+ d[")
569 assert_completion(line_buffer="(d[")
569 assert_completion(line_buffer="(d[")
570 assert_completion(line_buffer="C.data[")
570 assert_completion(line_buffer="C.data[")
571
571
572 # greedy flag
572 # greedy flag
573 def assert_completion(**kwargs):
573 def assert_completion(**kwargs):
574 _, matches = complete(**kwargs)
574 _, matches = complete(**kwargs)
575 nt.assert_in("get()['abc']", matches)
575 nt.assert_in("get()['abc']", matches)
576
576
577 assert_no_completion(line_buffer="get()[")
577 assert_no_completion(line_buffer="get()[")
578 with greedy_completion():
578 with greedy_completion():
579 assert_completion(line_buffer="get()[")
579 assert_completion(line_buffer="get()[")
580 assert_completion(line_buffer="get()['")
580 assert_completion(line_buffer="get()['")
581 assert_completion(line_buffer="get()['a")
581 assert_completion(line_buffer="get()['a")
582 assert_completion(line_buffer="get()['ab")
582 assert_completion(line_buffer="get()['ab")
583 assert_completion(line_buffer="get()['abc")
583 assert_completion(line_buffer="get()['abc")
584
584
585
585
586
586
587 def test_dict_key_completion_bytes():
587 def test_dict_key_completion_bytes():
588 """Test handling of bytes in dict key completion"""
588 """Test handling of bytes in dict key completion"""
589 ip = get_ipython()
589 ip = get_ipython()
590 complete = ip.Completer.complete
590 complete = ip.Completer.complete
591
591
592 ip.user_ns['d'] = {'abc': None, b'abd': None}
592 ip.user_ns['d'] = {'abc': None, b'abd': None}
593
593
594 _, matches = complete(line_buffer="d[")
594 _, matches = complete(line_buffer="d[")
595 nt.assert_in("'abc'", matches)
595 nt.assert_in("'abc'", matches)
596 nt.assert_in("b'abd'", matches)
596 nt.assert_in("b'abd'", matches)
597
597
598 if False: # not currently implemented
598 if False: # not currently implemented
599 _, matches = complete(line_buffer="d[b")
599 _, matches = complete(line_buffer="d[b")
600 nt.assert_in("b'abd'", matches)
600 nt.assert_in("b'abd'", matches)
601 nt.assert_not_in("b'abc'", matches)
601 nt.assert_not_in("b'abc'", matches)
602
602
603 _, matches = complete(line_buffer="d[b'")
603 _, matches = complete(line_buffer="d[b'")
604 nt.assert_in("abd", matches)
604 nt.assert_in("abd", matches)
605 nt.assert_not_in("abc", matches)
605 nt.assert_not_in("abc", matches)
606
606
607 _, matches = complete(line_buffer="d[B'")
607 _, matches = complete(line_buffer="d[B'")
608 nt.assert_in("abd", matches)
608 nt.assert_in("abd", matches)
609 nt.assert_not_in("abc", matches)
609 nt.assert_not_in("abc", matches)
610
610
611 _, matches = complete(line_buffer="d['")
611 _, matches = complete(line_buffer="d['")
612 nt.assert_in("abc", matches)
612 nt.assert_in("abc", matches)
613 nt.assert_not_in("abd", matches)
613 nt.assert_not_in("abd", matches)
614
614
615
615
616 def test_dict_key_completion_unicode_py3():
616 def test_dict_key_completion_unicode_py3():
617 """Test handling of unicode in dict key completion"""
617 """Test handling of unicode in dict key completion"""
618 ip = get_ipython()
618 ip = get_ipython()
619 complete = ip.Completer.complete
619 complete = ip.Completer.complete
620
620
621 ip.user_ns['d'] = {u'a\u05d0': None}
621 ip.user_ns['d'] = {u'a\u05d0': None}
622
622
623 # query using escape
623 # query using escape
624 if sys.platform != 'win32':
624 if sys.platform != 'win32':
625 # Known failure on Windows
625 # Known failure on Windows
626 _, matches = complete(line_buffer="d['a\\u05d0")
626 _, matches = complete(line_buffer="d['a\\u05d0")
627 nt.assert_in("u05d0", matches) # tokenized after \\
627 nt.assert_in("u05d0", matches) # tokenized after \\
628
628
629 # query using character
629 # query using character
630 _, matches = complete(line_buffer="d['a\u05d0")
630 _, matches = complete(line_buffer="d['a\u05d0")
631 nt.assert_in(u"a\u05d0", matches)
631 nt.assert_in(u"a\u05d0", matches)
632
632
633 with greedy_completion():
633 with greedy_completion():
634 # query using escape
634 # query using escape
635 _, matches = complete(line_buffer="d['a\\u05d0")
635 _, matches = complete(line_buffer="d['a\\u05d0")
636 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
636 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
637
637
638 # query using character
638 # query using character
639 _, matches = complete(line_buffer="d['a\u05d0")
639 _, matches = complete(line_buffer="d['a\u05d0")
640 nt.assert_in(u"d['a\u05d0']", matches)
640 nt.assert_in(u"d['a\u05d0']", matches)
641
641
642
642
643
643
644 @dec.skip_without('numpy')
644 @dec.skip_without('numpy')
645 def test_struct_array_key_completion():
645 def test_struct_array_key_completion():
646 """Test dict key completion applies to numpy struct arrays"""
646 """Test dict key completion applies to numpy struct arrays"""
647 import numpy
647 import numpy
648 ip = get_ipython()
648 ip = get_ipython()
649 complete = ip.Completer.complete
649 complete = ip.Completer.complete
650 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
650 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
651 _, matches = complete(line_buffer="d['")
651 _, matches = complete(line_buffer="d['")
652 nt.assert_in("hello", matches)
652 nt.assert_in("hello", matches)
653 nt.assert_in("world", matches)
653 nt.assert_in("world", matches)
654 # complete on the numpy struct itself
654 # complete on the numpy struct itself
655 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
655 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
656 ('my_data', '>f4', 5)])
656 ('my_data', '>f4', 5)])
657 x = numpy.zeros(2, dtype=dt)
657 x = numpy.zeros(2, dtype=dt)
658 ip.user_ns['d'] = x[1]
658 ip.user_ns['d'] = x[1]
659 _, matches = complete(line_buffer="d['")
659 _, matches = complete(line_buffer="d['")
660 nt.assert_in("my_head", matches)
660 nt.assert_in("my_head", matches)
661 nt.assert_in("my_data", matches)
661 nt.assert_in("my_data", matches)
662 # complete on a nested level
662 # complete on a nested level
663 with greedy_completion():
663 with greedy_completion():
664 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
664 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
665 _, matches = complete(line_buffer="d[1]['my_head']['")
665 _, matches = complete(line_buffer="d[1]['my_head']['")
666 nt.assert_true(any(["my_dt" in m for m in matches]))
666 nt.assert_true(any(["my_dt" in m for m in matches]))
667 nt.assert_true(any(["my_df" in m for m in matches]))
667 nt.assert_true(any(["my_df" in m for m in matches]))
668
668
669
669
670 @dec.skip_without('pandas')
670 @dec.skip_without('pandas')
671 def test_dataframe_key_completion():
671 def test_dataframe_key_completion():
672 """Test dict key completion applies to pandas DataFrames"""
672 """Test dict key completion applies to pandas DataFrames"""
673 import pandas
673 import pandas
674 ip = get_ipython()
674 ip = get_ipython()
675 complete = ip.Completer.complete
675 complete = ip.Completer.complete
676 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
676 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
677 _, matches = complete(line_buffer="d['")
677 _, matches = complete(line_buffer="d['")
678 nt.assert_in("hello", matches)
678 nt.assert_in("hello", matches)
679 nt.assert_in("world", matches)
679 nt.assert_in("world", matches)
680
680
681
681
682 def test_dict_key_completion_invalids():
682 def test_dict_key_completion_invalids():
683 """Smoke test cases dict key completion can't handle"""
683 """Smoke test cases dict key completion can't handle"""
684 ip = get_ipython()
684 ip = get_ipython()
685 complete = ip.Completer.complete
685 complete = ip.Completer.complete
686
686
687 ip.user_ns['no_getitem'] = None
687 ip.user_ns['no_getitem'] = None
688 ip.user_ns['no_keys'] = []
688 ip.user_ns['no_keys'] = []
689 ip.user_ns['cant_call_keys'] = dict
689 ip.user_ns['cant_call_keys'] = dict
690 ip.user_ns['empty'] = {}
690 ip.user_ns['empty'] = {}
691 ip.user_ns['d'] = {'abc': 5}
691 ip.user_ns['d'] = {'abc': 5}
692
692
693 _, matches = complete(line_buffer="no_getitem['")
693 _, matches = complete(line_buffer="no_getitem['")
694 _, matches = complete(line_buffer="no_keys['")
694 _, matches = complete(line_buffer="no_keys['")
695 _, matches = complete(line_buffer="cant_call_keys['")
695 _, matches = complete(line_buffer="cant_call_keys['")
696 _, matches = complete(line_buffer="empty['")
696 _, matches = complete(line_buffer="empty['")
697 _, matches = complete(line_buffer="name_error['")
697 _, matches = complete(line_buffer="name_error['")
698 _, matches = complete(line_buffer="d['\\") # incomplete escape
698 _, matches = complete(line_buffer="d['\\") # incomplete escape
699
699
700 class KeyCompletable(object):
700 class KeyCompletable(object):
701 def __init__(self, things=()):
701 def __init__(self, things=()):
702 self.things = things
702 self.things = things
703
703
704 def _ipython_key_completions_(self):
704 def _ipython_key_completions_(self):
705 return list(self.things)
705 return list(self.things)
706
706
707 def test_object_key_completion():
707 def test_object_key_completion():
708 ip = get_ipython()
708 ip = get_ipython()
709 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
709 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
710
710
711 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
711 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
712 nt.assert_in('qwerty', matches)
712 nt.assert_in('qwerty', matches)
713 nt.assert_in('qwick', matches)
713 nt.assert_in('qwick', matches)
714
714
715
715
716 def test_aimport_module_completer():
716 def test_aimport_module_completer():
717 ip = get_ipython()
717 ip = get_ipython()
718 _, matches = ip.complete('i', '%aimport i')
718 _, matches = ip.complete('i', '%aimport i')
719 nt.assert_in('io', matches)
719 nt.assert_in('io', matches)
720 nt.assert_not_in('int', matches)
720 nt.assert_not_in('int', matches)
721
721
722 def test_nested_import_module_completer():
722 def test_nested_import_module_completer():
723 ip = get_ipython()
723 ip = get_ipython()
724 _, matches = ip.complete(None, 'import IPython.co', 17)
724 _, matches = ip.complete(None, 'import IPython.co', 17)
725 nt.assert_in('IPython.core', matches)
725 nt.assert_in('IPython.core', matches)
726 nt.assert_not_in('import IPython.core', matches)
726 nt.assert_not_in('import IPython.core', matches)
727 nt.assert_not_in('IPython.display', matches)
727 nt.assert_not_in('IPython.display', matches)
728
728
729 def test_import_module_completer():
729 def test_import_module_completer():
730 ip = get_ipython()
730 ip = get_ipython()
731 _, matches = ip.complete('i', 'import i')
731 _, matches = ip.complete('i', 'import i')
732 nt.assert_in('io', matches)
732 nt.assert_in('io', matches)
733 nt.assert_not_in('int', matches)
733 nt.assert_not_in('int', matches)
734
734
735 def test_from_module_completer():
735 def test_from_module_completer():
736 ip = get_ipython()
736 ip = get_ipython()
737 _, matches = ip.complete('B', 'from io import B', 16)
737 _, matches = ip.complete('B', 'from io import B', 16)
738 nt.assert_in('BytesIO', matches)
738 nt.assert_in('BytesIO', matches)
739 nt.assert_not_in('BaseException', matches)
739 nt.assert_not_in('BaseException', matches)
@@ -1,496 +1,496 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.path.py"""
2 """Tests for IPython.utils.path.py"""
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 errno
7 import errno
8 import os
8 import os
9 import shutil
9 import shutil
10 import sys
10 import sys
11 import tempfile
11 import tempfile
12 import warnings
12 import warnings
13 from contextlib import contextmanager
13 from contextlib import contextmanager
14
14
15 try: # Python 3.3+
15 try: # Python 3.3+
16 from unittest.mock import patch
16 from unittest.mock import patch
17 except ImportError:
17 except ImportError:
18 from mock import patch
18 from mock import patch
19
19
20 from os.path import join, abspath, split
20 from os.path import join, abspath, split
21
21
22 from nose import SkipTest
22 from nose import SkipTest
23 import nose.tools as nt
23 import nose.tools as nt
24
24
25 from nose import with_setup
25 from nose import with_setup
26
26
27 import IPython
27 import IPython
28 from IPython import paths
28 from IPython import paths
29 from IPython.testing import decorators as dec
29 from IPython.testing import decorators as dec
30 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
30 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
31 onlyif_unicode_paths,)
31 onlyif_unicode_paths,)
32 from IPython.testing.tools import make_tempfile, AssertPrints
32 from IPython.testing.tools import make_tempfile, AssertPrints
33 from IPython.utils import path
33 from IPython.utils import path
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from IPython.utils.tempdir import TemporaryDirectory
35 from IPython.utils.tempdir import TemporaryDirectory
36
36
37 # Platform-dependent imports
37 # Platform-dependent imports
38 try:
38 try:
39 import winreg as wreg # Py 3
39 import winreg as wreg # Py 3
40 except ImportError:
40 except ImportError:
41 try:
41 try:
42 import _winreg as wreg # Py 2
42 import _winreg as wreg # Py 2
43 except ImportError:
43 except ImportError:
44 #Fake _winreg module on none windows platforms
44 #Fake _winreg module on none windows platforms
45 import types
45 import types
46 wr_name = "winreg" if py3compat.PY3 else "_winreg"
46 wr_name = "winreg" if py3compat.PY3 else "_winreg"
47 sys.modules[wr_name] = types.ModuleType(wr_name)
47 sys.modules[wr_name] = types.ModuleType(wr_name)
48 try:
48 try:
49 import winreg as wreg
49 import winreg as wreg
50 except ImportError:
50 except ImportError:
51 import _winreg as wreg
51 import _winreg as wreg
52 #Add entries that needs to be stubbed by the testing code
52 #Add entries that needs to be stubbed by the testing code
53 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
53 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
54
54
55 try:
55 try:
56 reload
56 reload
57 except NameError: # Python 3
57 except NameError: # Python 3
58 from imp import reload
58 from imp import reload
59
59
60 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
61 # Globals
61 # Globals
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63 env = os.environ
63 env = os.environ
64 TMP_TEST_DIR = tempfile.mkdtemp()
64 TMP_TEST_DIR = tempfile.mkdtemp()
65 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
65 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
66 #
66 #
67 # Setup/teardown functions/decorators
67 # Setup/teardown functions/decorators
68 #
68 #
69
69
70 def setup():
70 def setup():
71 """Setup testenvironment for the module:
71 """Setup testenvironment for the module:
72
72
73 - Adds dummy home dir tree
73 - Adds dummy home dir tree
74 """
74 """
75 # Do not mask exceptions here. In particular, catching WindowsError is a
75 # Do not mask exceptions here. In particular, catching WindowsError is a
76 # problem because that exception is only defined on Windows...
76 # problem because that exception is only defined on Windows...
77 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
77 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
78
78
79
79
80 def teardown():
80 def teardown():
81 """Teardown testenvironment for the module:
81 """Teardown testenvironment for the module:
82
82
83 - Remove dummy home dir tree
83 - Remove dummy home dir tree
84 """
84 """
85 # Note: we remove the parent test dir, which is the root of all test
85 # Note: we remove the parent test dir, which is the root of all test
86 # subdirs we may have created. Use shutil instead of os.removedirs, so
86 # subdirs we may have created. Use shutil instead of os.removedirs, so
87 # that non-empty directories are all recursively removed.
87 # that non-empty directories are all recursively removed.
88 shutil.rmtree(TMP_TEST_DIR)
88 shutil.rmtree(TMP_TEST_DIR)
89
89
90
90
91 def setup_environment():
91 def setup_environment():
92 """Setup testenvironment for some functions that are tested
92 """Setup testenvironment for some functions that are tested
93 in this module. In particular this functions stores attributes
93 in this module. In particular this functions stores attributes
94 and other things that we need to stub in some test functions.
94 and other things that we need to stub in some test functions.
95 This needs to be done on a function level and not module level because
95 This needs to be done on a function level and not module level because
96 each testfunction needs a pristine environment.
96 each testfunction needs a pristine environment.
97 """
97 """
98 global oldstuff, platformstuff
98 global oldstuff, platformstuff
99 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
99 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
100
100
101 def teardown_environment():
101 def teardown_environment():
102 """Restore things that were remembered by the setup_environment function
102 """Restore things that were remembered by the setup_environment function
103 """
103 """
104 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
104 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
105 os.chdir(old_wd)
105 os.chdir(old_wd)
106 reload(path)
106 reload(path)
107
107
108 for key in list(env):
108 for key in list(env):
109 if key not in oldenv:
109 if key not in oldenv:
110 del env[key]
110 del env[key]
111 env.update(oldenv)
111 env.update(oldenv)
112 if hasattr(sys, 'frozen'):
112 if hasattr(sys, 'frozen'):
113 del sys.frozen
113 del sys.frozen
114
114
115 # Build decorator that uses the setup_environment/setup_environment
115 # Build decorator that uses the setup_environment/setup_environment
116 with_environment = with_setup(setup_environment, teardown_environment)
116 with_environment = with_setup(setup_environment, teardown_environment)
117
117
118 @skip_if_not_win32
118 @skip_if_not_win32
119 @with_environment
119 @with_environment
120 def test_get_home_dir_1():
120 def test_get_home_dir_1():
121 """Testcase for py2exe logic, un-compressed lib
121 """Testcase for py2exe logic, un-compressed lib
122 """
122 """
123 unfrozen = path.get_home_dir()
123 unfrozen = path.get_home_dir()
124 sys.frozen = True
124 sys.frozen = True
125
125
126 #fake filename for IPython.__init__
126 #fake filename for IPython.__init__
127 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
127 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
128
128
129 home_dir = path.get_home_dir()
129 home_dir = path.get_home_dir()
130 nt.assert_equal(home_dir, unfrozen)
130 nt.assert_equal(home_dir, unfrozen)
131
131
132
132
133 @skip_if_not_win32
133 @skip_if_not_win32
134 @with_environment
134 @with_environment
135 def test_get_home_dir_2():
135 def test_get_home_dir_2():
136 """Testcase for py2exe logic, compressed lib
136 """Testcase for py2exe logic, compressed lib
137 """
137 """
138 unfrozen = path.get_home_dir()
138 unfrozen = path.get_home_dir()
139 sys.frozen = True
139 sys.frozen = True
140 #fake filename for IPython.__init__
140 #fake filename for IPython.__init__
141 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
141 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
142
142
143 home_dir = path.get_home_dir(True)
143 home_dir = path.get_home_dir(True)
144 nt.assert_equal(home_dir, unfrozen)
144 nt.assert_equal(home_dir, unfrozen)
145
145
146
146
147 @with_environment
147 @with_environment
148 def test_get_home_dir_3():
148 def test_get_home_dir_3():
149 """get_home_dir() uses $HOME if set"""
149 """get_home_dir() uses $HOME if set"""
150 env["HOME"] = HOME_TEST_DIR
150 env["HOME"] = HOME_TEST_DIR
151 home_dir = path.get_home_dir(True)
151 home_dir = path.get_home_dir(True)
152 # get_home_dir expands symlinks
152 # get_home_dir expands symlinks
153 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
153 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
154
154
155
155
156 @with_environment
156 @with_environment
157 def test_get_home_dir_4():
157 def test_get_home_dir_4():
158 """get_home_dir() still works if $HOME is not set"""
158 """get_home_dir() still works if $HOME is not set"""
159
159
160 if 'HOME' in env: del env['HOME']
160 if 'HOME' in env: del env['HOME']
161 # this should still succeed, but we don't care what the answer is
161 # this should still succeed, but we don't care what the answer is
162 home = path.get_home_dir(False)
162 home = path.get_home_dir(False)
163
163
164 @with_environment
164 @with_environment
165 def test_get_home_dir_5():
165 def test_get_home_dir_5():
166 """raise HomeDirError if $HOME is specified, but not a writable dir"""
166 """raise HomeDirError if $HOME is specified, but not a writable dir"""
167 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
167 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
168 # set os.name = posix, to prevent My Documents fallback on Windows
168 # set os.name = posix, to prevent My Documents fallback on Windows
169 os.name = 'posix'
169 os.name = 'posix'
170 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
170 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
171
171
172 # Should we stub wreg fully so we can run the test on all platforms?
172 # Should we stub wreg fully so we can run the test on all platforms?
173 @skip_if_not_win32
173 @skip_if_not_win32
174 @with_environment
174 @with_environment
175 def test_get_home_dir_8():
175 def test_get_home_dir_8():
176 """Using registry hack for 'My Documents', os=='nt'
176 """Using registry hack for 'My Documents', os=='nt'
177
177
178 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
178 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
179 """
179 """
180 os.name = 'nt'
180 os.name = 'nt'
181 # Remove from stub environment all keys that may be set
181 # Remove from stub environment all keys that may be set
182 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
182 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
183 env.pop(key, None)
183 env.pop(key, None)
184
184
185 class key:
185 class key:
186 def Close(self):
186 def Close(self):
187 pass
187 pass
188
188
189 with patch.object(wreg, 'OpenKey', return_value=key()), \
189 with patch.object(wreg, 'OpenKey', return_value=key()), \
190 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
190 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
191 home_dir = path.get_home_dir()
191 home_dir = path.get_home_dir()
192 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
192 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
193
193
194 @with_environment
194 @with_environment
195 def test_get_xdg_dir_0():
195 def test_get_xdg_dir_0():
196 """test_get_xdg_dir_0, check xdg_dir"""
196 """test_get_xdg_dir_0, check xdg_dir"""
197 reload(path)
197 reload(path)
198 path._writable_dir = lambda path: True
198 path._writable_dir = lambda path: True
199 path.get_home_dir = lambda : 'somewhere'
199 path.get_home_dir = lambda : 'somewhere'
200 os.name = "posix"
200 os.name = "posix"
201 sys.platform = "linux2"
201 sys.platform = "linux2"
202 env.pop('IPYTHON_DIR', None)
202 env.pop('IPYTHON_DIR', None)
203 env.pop('IPYTHONDIR', None)
203 env.pop('IPYTHONDIR', None)
204 env.pop('XDG_CONFIG_HOME', None)
204 env.pop('XDG_CONFIG_HOME', None)
205
205
206 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
206 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
207
207
208
208
209 @with_environment
209 @with_environment
210 def test_get_xdg_dir_1():
210 def test_get_xdg_dir_1():
211 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
211 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
212 reload(path)
212 reload(path)
213 path.get_home_dir = lambda : HOME_TEST_DIR
213 path.get_home_dir = lambda : HOME_TEST_DIR
214 os.name = "posix"
214 os.name = "posix"
215 sys.platform = "linux2"
215 sys.platform = "linux2"
216 env.pop('IPYTHON_DIR', None)
216 env.pop('IPYTHON_DIR', None)
217 env.pop('IPYTHONDIR', None)
217 env.pop('IPYTHONDIR', None)
218 env.pop('XDG_CONFIG_HOME', None)
218 env.pop('XDG_CONFIG_HOME', None)
219 nt.assert_equal(path.get_xdg_dir(), None)
219 nt.assert_equal(path.get_xdg_dir(), None)
220
220
221 @with_environment
221 @with_environment
222 def test_get_xdg_dir_2():
222 def test_get_xdg_dir_2():
223 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
223 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
224 reload(path)
224 reload(path)
225 path.get_home_dir = lambda : HOME_TEST_DIR
225 path.get_home_dir = lambda : HOME_TEST_DIR
226 os.name = "posix"
226 os.name = "posix"
227 sys.platform = "linux2"
227 sys.platform = "linux2"
228 env.pop('IPYTHON_DIR', None)
228 env.pop('IPYTHON_DIR', None)
229 env.pop('IPYTHONDIR', None)
229 env.pop('IPYTHONDIR', None)
230 env.pop('XDG_CONFIG_HOME', None)
230 env.pop('XDG_CONFIG_HOME', None)
231 cfgdir=os.path.join(path.get_home_dir(), '.config')
231 cfgdir=os.path.join(path.get_home_dir(), '.config')
232 if not os.path.exists(cfgdir):
232 if not os.path.exists(cfgdir):
233 os.makedirs(cfgdir)
233 os.makedirs(cfgdir)
234
234
235 nt.assert_equal(path.get_xdg_dir(), cfgdir)
235 nt.assert_equal(path.get_xdg_dir(), cfgdir)
236
236
237 @with_environment
237 @with_environment
238 def test_get_xdg_dir_3():
238 def test_get_xdg_dir_3():
239 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
239 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
240 reload(path)
240 reload(path)
241 path.get_home_dir = lambda : HOME_TEST_DIR
241 path.get_home_dir = lambda : HOME_TEST_DIR
242 os.name = "posix"
242 os.name = "posix"
243 sys.platform = "darwin"
243 sys.platform = "darwin"
244 env.pop('IPYTHON_DIR', None)
244 env.pop('IPYTHON_DIR', None)
245 env.pop('IPYTHONDIR', None)
245 env.pop('IPYTHONDIR', None)
246 env.pop('XDG_CONFIG_HOME', None)
246 env.pop('XDG_CONFIG_HOME', None)
247 cfgdir=os.path.join(path.get_home_dir(), '.config')
247 cfgdir=os.path.join(path.get_home_dir(), '.config')
248 if not os.path.exists(cfgdir):
248 if not os.path.exists(cfgdir):
249 os.makedirs(cfgdir)
249 os.makedirs(cfgdir)
250
250
251 nt.assert_equal(path.get_xdg_dir(), None)
251 nt.assert_equal(path.get_xdg_dir(), None)
252
252
253 def test_filefind():
253 def test_filefind():
254 """Various tests for filefind"""
254 """Various tests for filefind"""
255 f = tempfile.NamedTemporaryFile()
255 f = tempfile.NamedTemporaryFile()
256 # print 'fname:',f.name
256 # print 'fname:',f.name
257 alt_dirs = paths.get_ipython_dir()
257 alt_dirs = paths.get_ipython_dir()
258 t = path.filefind(f.name, alt_dirs)
258 t = path.filefind(f.name, alt_dirs)
259 # print 'found:',t
259 # print 'found:',t
260
260
261
261
262 @dec.skip_if_not_win32
262 @dec.skip_if_not_win32
263 def test_get_long_path_name_win32():
263 def test_get_long_path_name_win32():
264 with TemporaryDirectory() as tmpdir:
264 with TemporaryDirectory() as tmpdir:
265
265
266 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
266 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
267 # path component, so ensure we include the long form of it
267 # path component, so ensure we include the long form of it
268 long_path = os.path.join(path.get_long_path_name(tmpdir), u'this is my long path name')
268 long_path = os.path.join(path.get_long_path_name(tmpdir), u'this is my long path name')
269 os.makedirs(long_path)
269 os.makedirs(long_path)
270
270
271 # Test to see if the short path evaluates correctly.
271 # Test to see if the short path evaluates correctly.
272 short_path = os.path.join(tmpdir, u'THISIS~1')
272 short_path = os.path.join(tmpdir, u'THISIS~1')
273 evaluated_path = path.get_long_path_name(short_path)
273 evaluated_path = path.get_long_path_name(short_path)
274 nt.assert_equal(evaluated_path.lower(), long_path.lower())
274 nt.assert_equal(evaluated_path.lower(), long_path.lower())
275
275
276
276
277 @dec.skip_win32
277 @dec.skip_win32
278 def test_get_long_path_name():
278 def test_get_long_path_name():
279 p = path.get_long_path_name('/usr/local')
279 p = path.get_long_path_name('/usr/local')
280 nt.assert_equal(p,'/usr/local')
280 nt.assert_equal(p,'/usr/local')
281
281
282 @dec.skip_win32 # can't create not-user-writable dir on win
282 @dec.skip_win32 # can't create not-user-writable dir on win
283 @with_environment
283 @with_environment
284 def test_not_writable_ipdir():
284 def test_not_writable_ipdir():
285 tmpdir = tempfile.mkdtemp()
285 tmpdir = tempfile.mkdtemp()
286 os.name = "posix"
286 os.name = "posix"
287 env.pop('IPYTHON_DIR', None)
287 env.pop('IPYTHON_DIR', None)
288 env.pop('IPYTHONDIR', None)
288 env.pop('IPYTHONDIR', None)
289 env.pop('XDG_CONFIG_HOME', None)
289 env.pop('XDG_CONFIG_HOME', None)
290 env['HOME'] = tmpdir
290 env['HOME'] = tmpdir
291 ipdir = os.path.join(tmpdir, '.ipython')
291 ipdir = os.path.join(tmpdir, '.ipython')
292 os.mkdir(ipdir, 0o555)
292 os.mkdir(ipdir, 0o555)
293 try:
293 try:
294 open(os.path.join(ipdir, "_foo_"), 'w').close()
294 open(os.path.join(ipdir, "_foo_"), 'w').close()
295 except IOError:
295 except IOError:
296 pass
296 pass
297 else:
297 else:
298 # I can still write to an unwritable dir,
298 # I can still write to an unwritable dir,
299 # assume I'm root and skip the test
299 # assume I'm root and skip the test
300 raise SkipTest("I can't create directories that I can't write to")
300 raise SkipTest("I can't create directories that I can't write to")
301 with AssertPrints('is not a writable location', channel='stderr'):
301 with AssertPrints('is not a writable location', channel='stderr'):
302 ipdir = paths.get_ipython_dir()
302 ipdir = paths.get_ipython_dir()
303 env.pop('IPYTHON_DIR', None)
303 env.pop('IPYTHON_DIR', None)
304
304
305 @with_environment
305 @with_environment
306 def test_get_py_filename():
306 def test_get_py_filename():
307 os.chdir(TMP_TEST_DIR)
307 os.chdir(TMP_TEST_DIR)
308 with make_tempfile('foo.py'):
308 with make_tempfile('foo.py'):
309 nt.assert_equal(path.get_py_filename('foo.py'), 'foo.py')
309 nt.assert_equal(path.get_py_filename('foo.py'), 'foo.py')
310 nt.assert_equal(path.get_py_filename('foo'), 'foo.py')
310 nt.assert_equal(path.get_py_filename('foo'), 'foo.py')
311 with make_tempfile('foo'):
311 with make_tempfile('foo'):
312 nt.assert_equal(path.get_py_filename('foo'), 'foo')
312 nt.assert_equal(path.get_py_filename('foo'), 'foo')
313 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
313 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
314 nt.assert_raises(IOError, path.get_py_filename, 'foo')
314 nt.assert_raises(IOError, path.get_py_filename, 'foo')
315 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
315 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
316 true_fn = 'foo with spaces.py'
316 true_fn = 'foo with spaces.py'
317 with make_tempfile(true_fn):
317 with make_tempfile(true_fn):
318 nt.assert_equal(path.get_py_filename('foo with spaces'), true_fn)
318 nt.assert_equal(path.get_py_filename('foo with spaces'), true_fn)
319 nt.assert_equal(path.get_py_filename('foo with spaces.py'), true_fn)
319 nt.assert_equal(path.get_py_filename('foo with spaces.py'), true_fn)
320 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"')
320 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"')
321 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'")
321 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'")
322
322
323 @onlyif_unicode_paths
323 @onlyif_unicode_paths
324 def test_unicode_in_filename():
324 def test_unicode_in_filename():
325 """When a file doesn't exist, the exception raised should be safe to call
325 """When a file doesn't exist, the exception raised should be safe to call
326 str() on - i.e. in Python 2 it must only have ASCII characters.
326 str() on - i.e. in Python 2 it must only have ASCII characters.
327
327
328 https://github.com/ipython/ipython/issues/875
328 https://github.com/ipython/ipython/issues/875
329 """
329 """
330 try:
330 try:
331 # these calls should not throw unicode encode exceptions
331 # these calls should not throw unicode encode exceptions
332 path.get_py_filename(u'fooéè.py', force_win32=False)
332 path.get_py_filename(u'fooéè.py', force_win32=False)
333 except IOError as ex:
333 except IOError as ex:
334 str(ex)
334 str(ex)
335
335
336
336
337 class TestShellGlob(object):
337 class TestShellGlob(object):
338
338
339 @classmethod
339 @classmethod
340 def setUpClass(cls):
340 def setUpClass(cls):
341 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
341 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
342 cls.filenames_end_with_b = ['0b', '1b', '2b']
342 cls.filenames_end_with_b = ['0b', '1b', '2b']
343 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
343 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
344 cls.tempdir = TemporaryDirectory()
344 cls.tempdir = TemporaryDirectory()
345 td = cls.tempdir.name
345 td = cls.tempdir.name
346
346
347 with cls.in_tempdir():
347 with cls.in_tempdir():
348 # Create empty files
348 # Create empty files
349 for fname in cls.filenames:
349 for fname in cls.filenames:
350 open(os.path.join(td, fname), 'w').close()
350 open(os.path.join(td, fname), 'w').close()
351
351
352 @classmethod
352 @classmethod
353 def tearDownClass(cls):
353 def tearDownClass(cls):
354 cls.tempdir.cleanup()
354 cls.tempdir.cleanup()
355
355
356 @classmethod
356 @classmethod
357 @contextmanager
357 @contextmanager
358 def in_tempdir(cls):
358 def in_tempdir(cls):
359 save = py3compat.getcwd()
359 save = py3compat.getcwd()
360 try:
360 try:
361 os.chdir(cls.tempdir.name)
361 os.chdir(cls.tempdir.name)
362 yield
362 yield
363 finally:
363 finally:
364 os.chdir(save)
364 os.chdir(save)
365
365
366 def check_match(self, patterns, matches):
366 def check_match(self, patterns, matches):
367 with self.in_tempdir():
367 with self.in_tempdir():
368 # glob returns unordered list. that's why sorted is required.
368 # glob returns unordered list. that's why sorted is required.
369 nt.assert_equals(sorted(path.shellglob(patterns)),
369 nt.assert_equal(sorted(path.shellglob(patterns)),
370 sorted(matches))
370 sorted(matches))
371
371
372 def common_cases(self):
372 def common_cases(self):
373 return [
373 return [
374 (['*'], self.filenames),
374 (['*'], self.filenames),
375 (['a*'], self.filenames_start_with_a),
375 (['a*'], self.filenames_start_with_a),
376 (['*c'], ['*c']),
376 (['*c'], ['*c']),
377 (['*', 'a*', '*b', '*c'], self.filenames
377 (['*', 'a*', '*b', '*c'], self.filenames
378 + self.filenames_start_with_a
378 + self.filenames_start_with_a
379 + self.filenames_end_with_b
379 + self.filenames_end_with_b
380 + ['*c']),
380 + ['*c']),
381 (['a[012]'], self.filenames_start_with_a),
381 (['a[012]'], self.filenames_start_with_a),
382 ]
382 ]
383
383
384 @skip_win32
384 @skip_win32
385 def test_match_posix(self):
385 def test_match_posix(self):
386 for (patterns, matches) in self.common_cases() + [
386 for (patterns, matches) in self.common_cases() + [
387 ([r'\*'], ['*']),
387 ([r'\*'], ['*']),
388 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
388 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
389 ([r'a\[012]'], ['a[012]']),
389 ([r'a\[012]'], ['a[012]']),
390 ]:
390 ]:
391 yield (self.check_match, patterns, matches)
391 yield (self.check_match, patterns, matches)
392
392
393 @skip_if_not_win32
393 @skip_if_not_win32
394 def test_match_windows(self):
394 def test_match_windows(self):
395 for (patterns, matches) in self.common_cases() + [
395 for (patterns, matches) in self.common_cases() + [
396 # In windows, backslash is interpreted as path
396 # In windows, backslash is interpreted as path
397 # separator. Therefore, you can't escape glob
397 # separator. Therefore, you can't escape glob
398 # using it.
398 # using it.
399 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
399 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
400 ([r'a\[012]'], [r'a\[012]']),
400 ([r'a\[012]'], [r'a\[012]']),
401 ]:
401 ]:
402 yield (self.check_match, patterns, matches)
402 yield (self.check_match, patterns, matches)
403
403
404
404
405 def test_unescape_glob():
405 def test_unescape_glob():
406 nt.assert_equals(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
406 nt.assert_equal(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
407 nt.assert_equals(path.unescape_glob(r'\\*'), r'\*')
407 nt.assert_equal(path.unescape_glob(r'\\*'), r'\*')
408 nt.assert_equals(path.unescape_glob(r'\\\*'), r'\*')
408 nt.assert_equal(path.unescape_glob(r'\\\*'), r'\*')
409 nt.assert_equals(path.unescape_glob(r'\\a'), r'\a')
409 nt.assert_equal(path.unescape_glob(r'\\a'), r'\a')
410 nt.assert_equals(path.unescape_glob(r'\a'), r'\a')
410 nt.assert_equal(path.unescape_glob(r'\a'), r'\a')
411
411
412
412
413 def test_ensure_dir_exists():
413 def test_ensure_dir_exists():
414 with TemporaryDirectory() as td:
414 with TemporaryDirectory() as td:
415 d = os.path.join(td, u'βˆ‚ir')
415 d = os.path.join(td, u'βˆ‚ir')
416 path.ensure_dir_exists(d) # create it
416 path.ensure_dir_exists(d) # create it
417 assert os.path.isdir(d)
417 assert os.path.isdir(d)
418 path.ensure_dir_exists(d) # no-op
418 path.ensure_dir_exists(d) # no-op
419 f = os.path.join(td, u'Ζ’ile')
419 f = os.path.join(td, u'Ζ’ile')
420 open(f, 'w').close() # touch
420 open(f, 'w').close() # touch
421 with nt.assert_raises(IOError):
421 with nt.assert_raises(IOError):
422 path.ensure_dir_exists(f)
422 path.ensure_dir_exists(f)
423
423
424 class TestLinkOrCopy(object):
424 class TestLinkOrCopy(object):
425 def setUp(self):
425 def setUp(self):
426 self.tempdir = TemporaryDirectory()
426 self.tempdir = TemporaryDirectory()
427 self.src = self.dst("src")
427 self.src = self.dst("src")
428 with open(self.src, "w") as f:
428 with open(self.src, "w") as f:
429 f.write("Hello, world!")
429 f.write("Hello, world!")
430
430
431 def tearDown(self):
431 def tearDown(self):
432 self.tempdir.cleanup()
432 self.tempdir.cleanup()
433
433
434 def dst(self, *args):
434 def dst(self, *args):
435 return os.path.join(self.tempdir.name, *args)
435 return os.path.join(self.tempdir.name, *args)
436
436
437 def assert_inode_not_equal(self, a, b):
437 def assert_inode_not_equal(self, a, b):
438 nt.assert_not_equals(os.stat(a).st_ino, os.stat(b).st_ino,
438 nt.assert_not_equal(os.stat(a).st_ino, os.stat(b).st_ino,
439 "%r and %r do reference the same indoes" %(a, b))
439 "%r and %r do reference the same indoes" %(a, b))
440
440
441 def assert_inode_equal(self, a, b):
441 def assert_inode_equal(self, a, b):
442 nt.assert_equals(os.stat(a).st_ino, os.stat(b).st_ino,
442 nt.assert_equal(os.stat(a).st_ino, os.stat(b).st_ino,
443 "%r and %r do not reference the same indoes" %(a, b))
443 "%r and %r do not reference the same indoes" %(a, b))
444
444
445 def assert_content_equal(self, a, b):
445 def assert_content_equal(self, a, b):
446 with open(a) as a_f:
446 with open(a) as a_f:
447 with open(b) as b_f:
447 with open(b) as b_f:
448 nt.assert_equals(a_f.read(), b_f.read())
448 nt.assert_equal(a_f.read(), b_f.read())
449
449
450 @skip_win32
450 @skip_win32
451 def test_link_successful(self):
451 def test_link_successful(self):
452 dst = self.dst("target")
452 dst = self.dst("target")
453 path.link_or_copy(self.src, dst)
453 path.link_or_copy(self.src, dst)
454 self.assert_inode_equal(self.src, dst)
454 self.assert_inode_equal(self.src, dst)
455
455
456 @skip_win32
456 @skip_win32
457 def test_link_into_dir(self):
457 def test_link_into_dir(self):
458 dst = self.dst("some_dir")
458 dst = self.dst("some_dir")
459 os.mkdir(dst)
459 os.mkdir(dst)
460 path.link_or_copy(self.src, dst)
460 path.link_or_copy(self.src, dst)
461 expected_dst = self.dst("some_dir", os.path.basename(self.src))
461 expected_dst = self.dst("some_dir", os.path.basename(self.src))
462 self.assert_inode_equal(self.src, expected_dst)
462 self.assert_inode_equal(self.src, expected_dst)
463
463
464 @skip_win32
464 @skip_win32
465 def test_target_exists(self):
465 def test_target_exists(self):
466 dst = self.dst("target")
466 dst = self.dst("target")
467 open(dst, "w").close()
467 open(dst, "w").close()
468 path.link_or_copy(self.src, dst)
468 path.link_or_copy(self.src, dst)
469 self.assert_inode_equal(self.src, dst)
469 self.assert_inode_equal(self.src, dst)
470
470
471 @skip_win32
471 @skip_win32
472 def test_no_link(self):
472 def test_no_link(self):
473 real_link = os.link
473 real_link = os.link
474 try:
474 try:
475 del os.link
475 del os.link
476 dst = self.dst("target")
476 dst = self.dst("target")
477 path.link_or_copy(self.src, dst)
477 path.link_or_copy(self.src, dst)
478 self.assert_content_equal(self.src, dst)
478 self.assert_content_equal(self.src, dst)
479 self.assert_inode_not_equal(self.src, dst)
479 self.assert_inode_not_equal(self.src, dst)
480 finally:
480 finally:
481 os.link = real_link
481 os.link = real_link
482
482
483 @skip_if_not_win32
483 @skip_if_not_win32
484 def test_windows(self):
484 def test_windows(self):
485 dst = self.dst("target")
485 dst = self.dst("target")
486 path.link_or_copy(self.src, dst)
486 path.link_or_copy(self.src, dst)
487 self.assert_content_equal(self.src, dst)
487 self.assert_content_equal(self.src, dst)
488
488
489 def test_link_twice(self):
489 def test_link_twice(self):
490 # Linking the same file twice shouldn't leave duplicates around.
490 # Linking the same file twice shouldn't leave duplicates around.
491 # See https://github.com/ipython/ipython/issues/6450
491 # See https://github.com/ipython/ipython/issues/6450
492 dst = self.dst('target')
492 dst = self.dst('target')
493 path.link_or_copy(self.src, dst)
493 path.link_or_copy(self.src, dst)
494 path.link_or_copy(self.src, dst)
494 path.link_or_copy(self.src, dst)
495 self.assert_inode_equal(self.src, dst)
495 self.assert_inode_equal(self.src, dst)
496 nt.assert_equal(sorted(os.listdir(self.tempdir.name)), ['src', 'target'])
496 nt.assert_equal(sorted(os.listdir(self.tempdir.name)), ['src', 'target'])
General Comments 0
You need to be logged in to leave comments. Login now