Show More
@@ -260,7 +260,11 b' def magic_run_completer(self, event):' | |||||
260 | """Complete files that end in .py or .ipy or .ipynb for the %run command. |
|
260 | """Complete files that end in .py or .ipy or .ipynb for the %run command. | |
261 | """ |
|
261 | """ | |
262 | comps = arg_split(event.line, strict=False) |
|
262 | comps = arg_split(event.line, strict=False) | |
263 | relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"") |
|
263 | # relpath should be the current token that we need to complete. | |
|
264 | if (len(comps) > 1) and (not event.line.endswith(' ')): | |||
|
265 | relpath = comps[-1].strip("'\"") | |||
|
266 | else: | |||
|
267 | relpath = '' | |||
264 |
|
268 | |||
265 | #print("\nev=", event) # dbg |
|
269 | #print("\nev=", event) # dbg | |
266 | #print("rp=", relpath) # dbg |
|
270 | #print("rp=", relpath) # dbg | |
@@ -270,20 +274,23 b' def magic_run_completer(self, event):' | |||||
270 | isdir = os.path.isdir |
|
274 | isdir = os.path.isdir | |
271 | relpath, tilde_expand, tilde_val = expand_user(relpath) |
|
275 | relpath, tilde_expand, tilde_val = expand_user(relpath) | |
272 |
|
276 | |||
273 | dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)] |
|
|||
274 |
|
||||
275 | # Find if the user has already typed the first filename, after which we |
|
277 | # Find if the user has already typed the first filename, after which we | |
276 | # should complete on all files, since after the first one other files may |
|
278 | # should complete on all files, since after the first one other files may | |
277 | # be arguments to the input script. |
|
279 | # be arguments to the input script. | |
278 |
|
280 | |||
279 | if any(magic_run_re.match(c) for c in comps): |
|
281 | if any(magic_run_re.match(c) for c in comps): | |
280 |
|
|
282 | matches = [f.replace('\\','/') + ('/' if isdir(f) else '') | |
|
283 | for f in lglob(relpath+'*')] | |||
281 | else: |
|
284 | else: | |
|
285 | dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)] | |||
282 | pys = [f.replace('\\','/') |
|
286 | pys = [f.replace('\\','/') | |
283 | for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') + |
|
287 | for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') + | |
284 | lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')] |
|
288 | lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')] | |
|
289 | ||||
|
290 | matches = dirs + pys | |||
|
291 | ||||
285 | #print('run comp:', dirs+pys) # dbg |
|
292 | #print('run comp:', dirs+pys) # dbg | |
286 |
return [compress_user(p, tilde_expand, tilde_val) for p in |
|
293 | return [compress_user(p, tilde_expand, tilde_val) for p in matches] | |
287 |
|
294 | |||
288 |
|
295 | |||
289 | def cd_completer(self, event): |
|
296 | def cd_completer(self, event): |
@@ -15,6 +15,8 b' import tempfile' | |||||
15 | import unittest |
|
15 | import unittest | |
16 | from os.path import join |
|
16 | from os.path import join | |
17 |
|
17 | |||
|
18 | import nose.tools as nt | |||
|
19 | ||||
18 | from IPython.core.completerlib import magic_run_completer, module_completion |
|
20 | from IPython.core.completerlib import magic_run_completer, module_completion | |
19 | from IPython.utils import py3compat |
|
21 | from IPython.utils import py3compat | |
20 | from IPython.utils.tempdir import TemporaryDirectory |
|
22 | from IPython.utils.tempdir import TemporaryDirectory | |
@@ -29,11 +31,17 b' class MockEvent(object):' | |||||
29 | # Test functions begin |
|
31 | # Test functions begin | |
30 | #----------------------------------------------------------------------------- |
|
32 | #----------------------------------------------------------------------------- | |
31 | class Test_magic_run_completer(unittest.TestCase): |
|
33 | class Test_magic_run_completer(unittest.TestCase): | |
|
34 | files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"] | |||
|
35 | dirs = [u"adir/", "bdir/"] | |||
|
36 | ||||
32 | def setUp(self): |
|
37 | def setUp(self): | |
33 | self.BASETESTDIR = tempfile.mkdtemp() |
|
38 | self.BASETESTDIR = tempfile.mkdtemp() | |
34 | for fil in [u"aao.py", u"a.py", u"b.py"]: |
|
39 | for fil in self.files: | |
35 | with open(join(self.BASETESTDIR, fil), "w") as sfile: |
|
40 | with open(join(self.BASETESTDIR, fil), "w") as sfile: | |
36 | sfile.write("pass\n") |
|
41 | sfile.write("pass\n") | |
|
42 | for d in self.dirs: | |||
|
43 | os.mkdir(join(self.BASETESTDIR, d)) | |||
|
44 | ||||
37 | self.oldpath = py3compat.getcwd() |
|
45 | self.oldpath = py3compat.getcwd() | |
38 | os.chdir(self.BASETESTDIR) |
|
46 | os.chdir(self.BASETESTDIR) | |
39 |
|
47 | |||
@@ -47,7 +55,7 b' class Test_magic_run_completer(unittest.TestCase):' | |||||
47 | event = MockEvent(u"%run a") |
|
55 | event = MockEvent(u"%run a") | |
48 | mockself = None |
|
56 | mockself = None | |
49 | match = set(magic_run_completer(mockself, event)) |
|
57 | match = set(magic_run_completer(mockself, event)) | |
50 |
self.assertEqual(match, |
|
58 | self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"}) | |
51 |
|
59 | |||
52 | def test_2(self): |
|
60 | def test_2(self): | |
53 | """Test magic_run_completer, should match one alterntive |
|
61 | """Test magic_run_completer, should match one alterntive | |
@@ -62,23 +70,23 b' class Test_magic_run_completer(unittest.TestCase):' | |||||
62 | event = MockEvent(u'%run "a') |
|
70 | event = MockEvent(u'%run "a') | |
63 | mockself = None |
|
71 | mockself = None | |
64 | match = set(magic_run_completer(mockself, event)) |
|
72 | match = set(magic_run_completer(mockself, event)) | |
65 |
self.assertEqual(match, |
|
73 | self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"}) | |
66 |
|
74 | |||
67 |
def test_ |
|
75 | def test_completion_more_args(self): | |
68 | """Testing of issue https://github.com/ipython/ipython/issues/1107""" |
|
76 | event = MockEvent(u'%run a.py ') | |
69 | invalid_module_names = set(['foo-bar', 'foo:bar', '10foo']) |
|
77 | match = set(magic_run_completer(None, event)) | |
70 | valid_module_names = set(['foobar']) |
|
78 | self.assertEqual(match, set(self.files + self.dirs)) | |
71 | with TemporaryDirectory() as tmpdir: |
|
79 | ||
72 | sys.path.insert( 0, tmpdir ) |
|
80 | def test_completion_in_dir(self): | |
73 | for name in invalid_module_names | valid_module_names: |
|
81 | # Github issue #3459 | |
74 | filename = os.path.join(tmpdir, name + '.py') |
|
82 | event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a'))) | |
75 | open(filename, 'w').close() |
|
83 | print(repr(event.line)) | |
76 |
|
84 | match = set(magic_run_completer(None, event)) | ||
77 | s = set( module_completion('import foo') ) |
|
85 | # We specifically use replace here rather than normpath, because | |
78 | intersection = s.intersection(invalid_module_names) |
|
86 | # at one point there were duplicates 'adir' and 'adir/', and normpath | |
79 | self.assertFalse(intersection, intersection) |
|
87 | # would hide the failure for that. | |
80 |
|
88 | self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/') | ||
81 | assert valid_module_names.issubset(s), valid_module_names.intersection(s) |
|
89 | for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')}) | |
82 |
|
90 | |||
83 | class Test_magic_run_completer_nonascii(unittest.TestCase): |
|
91 | class Test_magic_run_completer_nonascii(unittest.TestCase): | |
84 | @onlyif_unicode_paths |
|
92 | @onlyif_unicode_paths | |
@@ -119,3 +127,21 b' class Test_magic_run_completer_nonascii(unittest.TestCase):' | |||||
119 | mockself = None |
|
127 | mockself = None | |
120 | match = set(magic_run_completer(mockself, event)) |
|
128 | match = set(magic_run_completer(mockself, event)) | |
121 | self.assertEqual(match, set([u"a.py", u"aaø.py"])) |
|
129 | self.assertEqual(match, set([u"a.py", u"aaø.py"])) | |
|
130 | ||||
|
131 | # module_completer: | |||
|
132 | ||||
|
133 | def test_import_invalid_module(): | |||
|
134 | """Testing of issue https://github.com/ipython/ipython/issues/1107""" | |||
|
135 | invalid_module_names = set(['foo-bar', 'foo:bar', '10foo']) | |||
|
136 | valid_module_names = set(['foobar']) | |||
|
137 | with TemporaryDirectory() as tmpdir: | |||
|
138 | sys.path.insert( 0, tmpdir ) | |||
|
139 | for name in invalid_module_names | valid_module_names: | |||
|
140 | filename = os.path.join(tmpdir, name + '.py') | |||
|
141 | open(filename, 'w').close() | |||
|
142 | ||||
|
143 | s = set( module_completion('import foo') ) | |||
|
144 | intersection = s.intersection(invalid_module_names) | |||
|
145 | nt.assert_equal(intersection, set()) | |||
|
146 | ||||
|
147 | assert valid_module_names.issubset(s), valid_module_names.intersection(s) |
General Comments 0
You need to be logged in to leave comments.
Login now