Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ccc8b20

Browse files
committed
Work around a bug in Python's shlex module with unicode input.
The problem appeared as a broken %popd, but ultimately the real bug is in Python itself. I added some more tests that exercise various parts that were breaking due to the original problem, to at least improve test coverage.
1 parent a469f3d commit ccc8b20

3 files changed

Lines changed: 41 additions & 9 deletions

File tree

IPython/core/tests/test_magic.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,35 @@ def doctest_time():
267267
Wall time: 0.00 s
268268
"""
269269

270+
270271
def test_doctest_mode():
271272
"Toggle doctest_mode twice, it should be a no-op and run without error"
272273
_ip.magic('doctest_mode')
273274
_ip.magic('doctest_mode')
275+
276+
277+
def test_parse_options():
278+
"""Tests for basic options parsing in magics."""
279+
# These are only the most minimal of tests, more should be added later. At
280+
# the very least we check that basic text/unicode calls work OK.
281+
nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
282+
nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
283+
274284

285+
def test_dirops():
286+
"""Test various directory handling operations."""
287+
curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
288+
289+
startdir = os.getcwd()
290+
ipdir = _ip.ipython_dir
291+
try:
292+
_ip.magic('cd "%s"' % ipdir)
293+
nt.assert_equal(curpath(), ipdir)
294+
_ip.magic('cd -')
295+
nt.assert_equal(curpath(), startdir)
296+
_ip.magic('pushd "%s"' % ipdir)
297+
nt.assert_equal(curpath(), ipdir)
298+
_ip.magic('popd')
299+
nt.assert_equal(curpath(), startdir)
300+
finally:
301+
os.chdir(startdir)

IPython/utils/process.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,12 @@ def arg_split(s, posix=False):
136136
function, but with a default of posix=False for splitting, so that quotes
137137
in inputs are respected."""
138138

139-
# XXX - there may be unicode-related problems here!!! I'm not sure that
140-
# shlex is truly unicode-safe, so it might be necessary to do
141-
#
142-
# s = s.encode(sys.stdin.encoding)
143-
#
144-
# first, to ensure that shlex gets a normal string. Input from anyone who
145-
# knows more about unicode and shlex than I would be good to have here...
139+
# Unfortunately, python's shlex module is buggy with unicode input:
140+
# http://bugs.python.org/issue1170
141+
# At least encoding the input when it's unicode seems to help, but there
142+
# may be more problems lurking. Apparently this is fixed in python3.
143+
if isinstance(s, unicode):
144+
s = s.encode(sys.stdin.encoding)
146145
lex = shlex.shlex(s, posix=posix)
147146
lex.whitespace_split = True
148147
return list(lex)

IPython/utils/tests/test_process.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import nose.tools as nt
2020

21-
from IPython.utils.process import find_cmd, FindCmdError
21+
from IPython.utils.process import find_cmd, FindCmdError, arg_split
2222
from IPython.testing import decorators as dec
2323

2424
#-----------------------------------------------------------------------------
@@ -59,4 +59,10 @@ def test_find_cmd_fail():
5959
nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
6060

6161

62-
62+
def test_arg_split():
63+
"""Ensure that argument lines are correctly split like in a shell."""
64+
tests = [['hi', ['hi']],
65+
[u'hi', [u'hi']],
66+
]
67+
for argstr, argv in tests:
68+
nt.assert_equal(arg_split(argstr), argv)

0 commit comments

Comments
 (0)