diff --git a/IPython/core/completerlib.py b/IPython/core/completerlib.py index 850fe33..b03ad5e 100644 --- a/IPython/core/completerlib.py +++ b/IPython/core/completerlib.py @@ -20,7 +20,6 @@ import glob import inspect import os import re -import shlex import sys # Third-party imports @@ -31,6 +30,7 @@ from zipimport import zipimporter from IPython.core.completer import expand_user, compress_user from IPython.core.error import TryNext from IPython.utils import py3compat +from IPython.utils._process_common import arg_split # FIXME: this should be pulled in with the right call via the component system from IPython.core.ipapi import get as get_ipython @@ -56,40 +56,6 @@ magic_run_re = re.compile(r'.*(\.ipy|\.py[w]?)$') # Local utilities #----------------------------------------------------------------------------- -def shlex_split(x): - """Helper function to split lines into segments. - """ - # shlex.split raises an exception if there is a syntax error in sh syntax - # for example if no closing " is found. This function keeps dropping the - # last character of the line until shlex.split does not raise - # an exception. It adds end of the line to the result of shlex.split - # - # Example: - # %run "c:/python -> ['%run','"c:/python'] - - # shlex.split has unicode bugs in Python 2, so encode first to str - if not py3compat.PY3: - x = py3compat.cast_bytes(x) - - endofline = [] - while x != '': - try: - comps = shlex.split(x) - if len(endofline) >= 1: - comps.append(''.join(endofline)) - if not py3compat.PY3: - comps = [py3compat.cast_unicode(x) for x in comps] - return comps - - except ValueError: - endofline = [x[-1:]]+endofline - x = x[:-1] - - x = ''.join(endofline) - if not py3compat.PY3: - x = py3compat.cast_unicode(x) - return [x] - def module_list(path): """ Return the list containing the names of the modules available in the given @@ -270,7 +236,7 @@ def module_completer(self,event): def magic_run_completer(self, event): """Complete files that end in .py or .ipy for the %run command. """ - comps = shlex_split(event.line) + comps = arg_split(event.line) relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"") #print("\nev=", event) # dbg diff --git a/IPython/core/tests/test_completerlib.py b/IPython/core/tests/test_completerlib.py new file mode 100644 index 0000000..94af88c --- /dev/null +++ b/IPython/core/tests/test_completerlib.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +"""Tests for completerlib. + +""" +from __future__ import absolute_import + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import shutil +import sys +import tempfile +import unittest +from os.path import join + +import nose.tools as nt +from nose import SkipTest + +from IPython.core.completerlib import magic_run_completer +from IPython.testing import decorators as dec +from IPython.testing import tools as tt +from IPython.utils import py3compat + + +class MockEvent(object): + def __init__(self, line): + self.line = line + +#----------------------------------------------------------------------------- +# Test functions begin +#----------------------------------------------------------------------------- +class Test_magic_run_completer(unittest.TestCase): + def setUp(self): + self.BASETESTDIR = tempfile.mkdtemp() + for fil in [u"aaå.py", u"a.py", u"b.py"]: + with open(join(self.BASETESTDIR, fil), "w") as sfile: + sfile.write("pass\n") + self.oldpath = os.getcwdu() + os.chdir(self.BASETESTDIR) + + def tearDown(self): + os.chdir(self.oldpath) + shutil.rmtree(self.BASETESTDIR) + + def test_1(self): + """Test magic_run_completer, should match two alterntives + """ + event = MockEvent(u"%run a") + mockself = None + match = magic_run_completer(mockself, event) + self.assertEqual(match, [u"a.py", u"aaå.py",]) + + def test_2(self): + """Test magic_run_completer, should match one alterntive + """ + event = MockEvent(u"%run aa") + mockself = None + match = magic_run_completer(mockself, event) + self.assertEqual(match, [u"aaå.py",])