import io import shlex import string import unittest from test import support # The original test data set was from shellwords, by Hartmut Goebel. data = r"""x|x| foo bar|foo|bar| foo bar|foo|bar| foo bar |foo|bar| foo bar bla fasel|foo|bar|bla|fasel| x y z xxxx|x|y|z|xxxx| \x bar|\|x|bar| \ x bar|\|x|bar| \ bar|\|bar| foo \x bar|foo|\|x|bar| foo \ x bar|foo|\|x|bar| foo \ bar|foo|\|bar| foo "bar" bla|foo|"bar"|bla| "foo" "bar" "bla"|"foo"|"bar"|"bla"| "foo" bar "bla"|"foo"|bar|"bla"| "foo" bar bla|"foo"|bar|bla| foo 'bar' bla|foo|'bar'|bla| 'foo' 'bar' 'bla'|'foo'|'bar'|'bla'| 'foo' bar 'bla'|'foo'|bar|'bla'| 'foo' bar bla|'foo'|bar|bla| blurb foo"bar"bar"fasel" baz|blurb|foo"bar"bar"fasel"|baz| blurb foo'bar'bar'fasel' baz|blurb|foo'bar'bar'fasel'|baz| ""|""| ''|''| foo "" bar|foo|""|bar| foo '' bar|foo|''|bar| foo "" "" "" bar|foo|""|""|""|bar| foo '' '' '' bar|foo|''|''|''|bar| \""|\|""| "\"|"\"| "foo\ bar"|"foo\ bar"| "foo\\ bar"|"foo\\ bar"| "foo\\ bar\"|"foo\\ bar\"| "foo\\" bar\""|"foo\\"|bar|\|""| "foo\\ bar\" dfadf"|"foo\\ bar\"|dfadf"| "foo\\\ bar\" dfadf"|"foo\\\ bar\"|dfadf"| "foo\\\x bar\" dfadf"|"foo\\\x bar\"|dfadf"| "foo\x bar\" dfadf"|"foo\x bar\"|dfadf"| \''|\|''| 'foo\ bar'|'foo\ bar'| 'foo\\ bar'|'foo\\ bar'| "foo\\\x bar\" df'a\ 'df'|"foo\\\x bar\"|df'a|\|'df'| \"foo"|\|"foo"| \"foo"\x|\|"foo"|\|x| "foo\x"|"foo\x"| "foo\ "|"foo\ "| foo\ xx|foo|\|xx| foo\ x\x|foo|\|x|\|x| foo\ x\x\""|foo|\|x|\|x|\|""| "foo\ x\x"|"foo\ x\x"| "foo\ x\x\\"|"foo\ x\x\\"| "foo\ x\x\\""foobar"|"foo\ x\x\\"|"foobar"| "foo\ x\x\\"\''"foobar"|"foo\ x\x\\"|\|''|"foobar"| "foo\ x\x\\"\'"fo'obar"|"foo\ x\x\\"|\|'"fo'|obar"| "foo\ x\x\\"\'"fo'obar" 'don'\''t'|"foo\ x\x\\"|\|'"fo'|obar"|'don'|\|''|t'| 'foo\ bar'|'foo\ bar'| 'foo\\ bar'|'foo\\ bar'| foo\ bar|foo|\|bar| foo#bar\nbaz|foobaz| :-) ;-)|:|-|)|;|-|)| áéíóú|á|é|í|ó|ú| """ posix_data = r"""x|x| foo bar|foo|bar| foo bar|foo|bar| foo bar |foo|bar| foo bar bla fasel|foo|bar|bla|fasel| x y z xxxx|x|y|z|xxxx| \x bar|x|bar| \ x bar| x|bar| \ bar| bar| foo \x bar|foo|x|bar| foo \ x bar|foo| x|bar| foo \ bar|foo| bar| foo "bar" bla|foo|bar|bla| "foo" "bar" "bla"|foo|bar|bla| "foo" bar "bla"|foo|bar|bla| "foo" bar bla|foo|bar|bla| foo 'bar' bla|foo|bar|bla| 'foo' 'bar' 'bla'|foo|bar|bla| 'foo' bar 'bla'|foo|bar|bla| 'foo' bar bla|foo|bar|bla| blurb foo"bar"bar"fasel" baz|blurb|foobarbarfasel|baz| blurb foo'bar'bar'fasel' baz|blurb|foobarbarfasel|baz| ""|| ''|| foo "" bar|foo||bar| foo '' bar|foo||bar| foo "" "" "" bar|foo||||bar| foo '' '' '' bar|foo||||bar| \"|"| "\""|"| "foo\ bar"|foo\ bar| "foo\\ bar"|foo\ bar| "foo\\ bar\""|foo\ bar"| "foo\\" bar\"|foo\|bar"| "foo\\ bar\" dfadf"|foo\ bar" dfadf| "foo\\\ bar\" dfadf"|foo\\ bar" dfadf| "foo\\\x bar\" dfadf"|foo\\x bar" dfadf| "foo\x bar\" dfadf"|foo\x bar" dfadf| \'|'| 'foo\ bar'|foo\ bar| 'foo\\ bar'|foo\\ bar| "foo\\\x bar\" df'a\ 'df"|foo\\x bar" df'a\ 'df| \"foo|"foo| \"foo\x|"foox| "foo\x"|foo\x| "foo\ "|foo\ | foo\ xx|foo xx| foo\ x\x|foo xx| foo\ x\x\"|foo xx"| "foo\ x\x"|foo\ x\x| "foo\ x\x\\"|foo\ x\x\| "foo\ x\x\\""foobar"|foo\ x\x\foobar| "foo\ x\x\\"\'"foobar"|foo\ x\x\'foobar| "foo\ x\x\\"\'"fo'obar"|foo\ x\x\'fo'obar| "foo\ x\x\\"\'"fo'obar" 'don'\''t'|foo\ x\x\'fo'obar|don't| "foo\ x\x\\"\'"fo'obar" 'don'\''t' \\|foo\ x\x\'fo'obar|don't|\| 'foo\ bar'|foo\ bar| 'foo\\ bar'|foo\\ bar| foo\ bar|foo bar| foo#bar\nbaz|foo|baz| :-) ;-)|:-)|;-)| áéíóú|áéíóú| """ class ShlexTest(unittest.TestCase): def setUp(self): self.data = [x.split("|")[:-1] for x in data.splitlines()] self.posix_data = [x.split("|")[:-1] for x in posix_data.splitlines()] for item in self.data: item[0] = item[0].replace(r"\n", "\n") for item in self.posix_data: item[0] = item[0].replace(r"\n", "\n") def splitTest(self, data, comments): for i in range(len(data)): l = shlex.split(data[i][0], comments=comments) self.assertEqual(l, data[i][1:], "%s: %s != %s" % (data[i][0], l, data[i][1:])) def oldSplit(self, s): ret = [] lex = shlex.shlex(io.StringIO(s)) tok = lex.get_token() while tok: ret.append(tok) tok = lex.get_token() return ret def testSplitPosix(self): """Test data splitting with posix parser""" self.splitTest(self.posix_data, comments=True) def testCompat(self): """Test compatibility interface""" for i in range(len(self.data)): l = self.oldSplit(self.data[i][0]) self.assertEqual(l, self.data[i][1:], "%s: %s != %s" % (self.data[i][0], l, self.data[i][1:])) def testQuote(self): safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./' unsafe = '"`$\\!' self.assertEqual(shlex.quote(''), "''") self.assertEqual(shlex.quote(safeunquoted), safeunquoted) self.assertEqual(shlex.quote('test file name'), "'test file name'") for u in unsafe: self.assertEqual(shlex.quote('test%sname' % u), "'test%sname'" % u) for u in unsafe: self.assertEqual(shlex.quote("test%s'name'" % u), "'test%s'\"'\"'name'\"'\"''" % u) # Allow this test to be used with old shlex.py if not getattr(shlex, "split", None): for methname in dir(ShlexTest): if methname.startswith("test") and methname != "testCompat": delattr(ShlexTest, methname) def test_main(): support.run_unittest(ShlexTest) if __name__ == "__main__": test_main()