17db96d56Sopenharmony_ciimport io 27db96d56Sopenharmony_ciimport itertools 37db96d56Sopenharmony_ciimport shlex 47db96d56Sopenharmony_ciimport string 57db96d56Sopenharmony_ciimport unittest 67db96d56Sopenharmony_cifrom unittest import mock 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci# The original test data set was from shellwords, by Hartmut Goebel. 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_cidata = r"""x|x| 127db96d56Sopenharmony_cifoo bar|foo|bar| 137db96d56Sopenharmony_ci foo bar|foo|bar| 147db96d56Sopenharmony_ci foo bar |foo|bar| 157db96d56Sopenharmony_cifoo bar bla fasel|foo|bar|bla|fasel| 167db96d56Sopenharmony_cix y z xxxx|x|y|z|xxxx| 177db96d56Sopenharmony_ci\x bar|\|x|bar| 187db96d56Sopenharmony_ci\ x bar|\|x|bar| 197db96d56Sopenharmony_ci\ bar|\|bar| 207db96d56Sopenharmony_cifoo \x bar|foo|\|x|bar| 217db96d56Sopenharmony_cifoo \ x bar|foo|\|x|bar| 227db96d56Sopenharmony_cifoo \ bar|foo|\|bar| 237db96d56Sopenharmony_cifoo "bar" bla|foo|"bar"|bla| 247db96d56Sopenharmony_ci"foo" "bar" "bla"|"foo"|"bar"|"bla"| 257db96d56Sopenharmony_ci"foo" bar "bla"|"foo"|bar|"bla"| 267db96d56Sopenharmony_ci"foo" bar bla|"foo"|bar|bla| 277db96d56Sopenharmony_cifoo 'bar' bla|foo|'bar'|bla| 287db96d56Sopenharmony_ci'foo' 'bar' 'bla'|'foo'|'bar'|'bla'| 297db96d56Sopenharmony_ci'foo' bar 'bla'|'foo'|bar|'bla'| 307db96d56Sopenharmony_ci'foo' bar bla|'foo'|bar|bla| 317db96d56Sopenharmony_ciblurb foo"bar"bar"fasel" baz|blurb|foo"bar"bar"fasel"|baz| 327db96d56Sopenharmony_ciblurb foo'bar'bar'fasel' baz|blurb|foo'bar'bar'fasel'|baz| 337db96d56Sopenharmony_ci""|""| 347db96d56Sopenharmony_ci''|''| 357db96d56Sopenharmony_cifoo "" bar|foo|""|bar| 367db96d56Sopenharmony_cifoo '' bar|foo|''|bar| 377db96d56Sopenharmony_cifoo "" "" "" bar|foo|""|""|""|bar| 387db96d56Sopenharmony_cifoo '' '' '' bar|foo|''|''|''|bar| 397db96d56Sopenharmony_ci\""|\|""| 407db96d56Sopenharmony_ci"\"|"\"| 417db96d56Sopenharmony_ci"foo\ bar"|"foo\ bar"| 427db96d56Sopenharmony_ci"foo\\ bar"|"foo\\ bar"| 437db96d56Sopenharmony_ci"foo\\ bar\"|"foo\\ bar\"| 447db96d56Sopenharmony_ci"foo\\" bar\""|"foo\\"|bar|\|""| 457db96d56Sopenharmony_ci"foo\\ bar\" dfadf"|"foo\\ bar\"|dfadf"| 467db96d56Sopenharmony_ci"foo\\\ bar\" dfadf"|"foo\\\ bar\"|dfadf"| 477db96d56Sopenharmony_ci"foo\\\x bar\" dfadf"|"foo\\\x bar\"|dfadf"| 487db96d56Sopenharmony_ci"foo\x bar\" dfadf"|"foo\x bar\"|dfadf"| 497db96d56Sopenharmony_ci\''|\|''| 507db96d56Sopenharmony_ci'foo\ bar'|'foo\ bar'| 517db96d56Sopenharmony_ci'foo\\ bar'|'foo\\ bar'| 527db96d56Sopenharmony_ci"foo\\\x bar\" df'a\ 'df'|"foo\\\x bar\"|df'a|\|'df'| 537db96d56Sopenharmony_ci\"foo"|\|"foo"| 547db96d56Sopenharmony_ci\"foo"\x|\|"foo"|\|x| 557db96d56Sopenharmony_ci"foo\x"|"foo\x"| 567db96d56Sopenharmony_ci"foo\ "|"foo\ "| 577db96d56Sopenharmony_cifoo\ xx|foo|\|xx| 587db96d56Sopenharmony_cifoo\ x\x|foo|\|x|\|x| 597db96d56Sopenharmony_cifoo\ x\x\""|foo|\|x|\|x|\|""| 607db96d56Sopenharmony_ci"foo\ x\x"|"foo\ x\x"| 617db96d56Sopenharmony_ci"foo\ x\x\\"|"foo\ x\x\\"| 627db96d56Sopenharmony_ci"foo\ x\x\\""foobar"|"foo\ x\x\\"|"foobar"| 637db96d56Sopenharmony_ci"foo\ x\x\\"\''"foobar"|"foo\ x\x\\"|\|''|"foobar"| 647db96d56Sopenharmony_ci"foo\ x\x\\"\'"fo'obar"|"foo\ x\x\\"|\|'"fo'|obar"| 657db96d56Sopenharmony_ci"foo\ x\x\\"\'"fo'obar" 'don'\''t'|"foo\ x\x\\"|\|'"fo'|obar"|'don'|\|''|t'| 667db96d56Sopenharmony_ci'foo\ bar'|'foo\ bar'| 677db96d56Sopenharmony_ci'foo\\ bar'|'foo\\ bar'| 687db96d56Sopenharmony_cifoo\ bar|foo|\|bar| 697db96d56Sopenharmony_cifoo#bar\nbaz|foobaz| 707db96d56Sopenharmony_ci:-) ;-)|:|-|)|;|-|)| 717db96d56Sopenharmony_ciáéíóú|á|é|í|ó|ú| 727db96d56Sopenharmony_ci""" 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ciposix_data = r"""x|x| 757db96d56Sopenharmony_cifoo bar|foo|bar| 767db96d56Sopenharmony_ci foo bar|foo|bar| 777db96d56Sopenharmony_ci foo bar |foo|bar| 787db96d56Sopenharmony_cifoo bar bla fasel|foo|bar|bla|fasel| 797db96d56Sopenharmony_cix y z xxxx|x|y|z|xxxx| 807db96d56Sopenharmony_ci\x bar|x|bar| 817db96d56Sopenharmony_ci\ x bar| x|bar| 827db96d56Sopenharmony_ci\ bar| bar| 837db96d56Sopenharmony_cifoo \x bar|foo|x|bar| 847db96d56Sopenharmony_cifoo \ x bar|foo| x|bar| 857db96d56Sopenharmony_cifoo \ bar|foo| bar| 867db96d56Sopenharmony_cifoo "bar" bla|foo|bar|bla| 877db96d56Sopenharmony_ci"foo" "bar" "bla"|foo|bar|bla| 887db96d56Sopenharmony_ci"foo" bar "bla"|foo|bar|bla| 897db96d56Sopenharmony_ci"foo" bar bla|foo|bar|bla| 907db96d56Sopenharmony_cifoo 'bar' bla|foo|bar|bla| 917db96d56Sopenharmony_ci'foo' 'bar' 'bla'|foo|bar|bla| 927db96d56Sopenharmony_ci'foo' bar 'bla'|foo|bar|bla| 937db96d56Sopenharmony_ci'foo' bar bla|foo|bar|bla| 947db96d56Sopenharmony_ciblurb foo"bar"bar"fasel" baz|blurb|foobarbarfasel|baz| 957db96d56Sopenharmony_ciblurb foo'bar'bar'fasel' baz|blurb|foobarbarfasel|baz| 967db96d56Sopenharmony_ci""|| 977db96d56Sopenharmony_ci''|| 987db96d56Sopenharmony_cifoo "" bar|foo||bar| 997db96d56Sopenharmony_cifoo '' bar|foo||bar| 1007db96d56Sopenharmony_cifoo "" "" "" bar|foo||||bar| 1017db96d56Sopenharmony_cifoo '' '' '' bar|foo||||bar| 1027db96d56Sopenharmony_ci\"|"| 1037db96d56Sopenharmony_ci"\""|"| 1047db96d56Sopenharmony_ci"foo\ bar"|foo\ bar| 1057db96d56Sopenharmony_ci"foo\\ bar"|foo\ bar| 1067db96d56Sopenharmony_ci"foo\\ bar\""|foo\ bar"| 1077db96d56Sopenharmony_ci"foo\\" bar\"|foo\|bar"| 1087db96d56Sopenharmony_ci"foo\\ bar\" dfadf"|foo\ bar" dfadf| 1097db96d56Sopenharmony_ci"foo\\\ bar\" dfadf"|foo\\ bar" dfadf| 1107db96d56Sopenharmony_ci"foo\\\x bar\" dfadf"|foo\\x bar" dfadf| 1117db96d56Sopenharmony_ci"foo\x bar\" dfadf"|foo\x bar" dfadf| 1127db96d56Sopenharmony_ci\'|'| 1137db96d56Sopenharmony_ci'foo\ bar'|foo\ bar| 1147db96d56Sopenharmony_ci'foo\\ bar'|foo\\ bar| 1157db96d56Sopenharmony_ci"foo\\\x bar\" df'a\ 'df"|foo\\x bar" df'a\ 'df| 1167db96d56Sopenharmony_ci\"foo|"foo| 1177db96d56Sopenharmony_ci\"foo\x|"foox| 1187db96d56Sopenharmony_ci"foo\x"|foo\x| 1197db96d56Sopenharmony_ci"foo\ "|foo\ | 1207db96d56Sopenharmony_cifoo\ xx|foo xx| 1217db96d56Sopenharmony_cifoo\ x\x|foo xx| 1227db96d56Sopenharmony_cifoo\ x\x\"|foo xx"| 1237db96d56Sopenharmony_ci"foo\ x\x"|foo\ x\x| 1247db96d56Sopenharmony_ci"foo\ x\x\\"|foo\ x\x\| 1257db96d56Sopenharmony_ci"foo\ x\x\\""foobar"|foo\ x\x\foobar| 1267db96d56Sopenharmony_ci"foo\ x\x\\"\'"foobar"|foo\ x\x\'foobar| 1277db96d56Sopenharmony_ci"foo\ x\x\\"\'"fo'obar"|foo\ x\x\'fo'obar| 1287db96d56Sopenharmony_ci"foo\ x\x\\"\'"fo'obar" 'don'\''t'|foo\ x\x\'fo'obar|don't| 1297db96d56Sopenharmony_ci"foo\ x\x\\"\'"fo'obar" 'don'\''t' \\|foo\ x\x\'fo'obar|don't|\| 1307db96d56Sopenharmony_ci'foo\ bar'|foo\ bar| 1317db96d56Sopenharmony_ci'foo\\ bar'|foo\\ bar| 1327db96d56Sopenharmony_cifoo\ bar|foo bar| 1337db96d56Sopenharmony_cifoo#bar\nbaz|foo|baz| 1347db96d56Sopenharmony_ci:-) ;-)|:-)|;-)| 1357db96d56Sopenharmony_ciáéíóú|áéíóú| 1367db96d56Sopenharmony_ci""" 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ciclass ShlexTest(unittest.TestCase): 1397db96d56Sopenharmony_ci def setUp(self): 1407db96d56Sopenharmony_ci self.data = [x.split("|")[:-1] 1417db96d56Sopenharmony_ci for x in data.splitlines()] 1427db96d56Sopenharmony_ci self.posix_data = [x.split("|")[:-1] 1437db96d56Sopenharmony_ci for x in posix_data.splitlines()] 1447db96d56Sopenharmony_ci for item in self.data: 1457db96d56Sopenharmony_ci item[0] = item[0].replace(r"\n", "\n") 1467db96d56Sopenharmony_ci for item in self.posix_data: 1477db96d56Sopenharmony_ci item[0] = item[0].replace(r"\n", "\n") 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci def splitTest(self, data, comments): 1507db96d56Sopenharmony_ci for i in range(len(data)): 1517db96d56Sopenharmony_ci l = shlex.split(data[i][0], comments=comments) 1527db96d56Sopenharmony_ci self.assertEqual(l, data[i][1:], 1537db96d56Sopenharmony_ci "%s: %s != %s" % 1547db96d56Sopenharmony_ci (data[i][0], l, data[i][1:])) 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci def oldSplit(self, s): 1577db96d56Sopenharmony_ci ret = [] 1587db96d56Sopenharmony_ci lex = shlex.shlex(io.StringIO(s)) 1597db96d56Sopenharmony_ci tok = lex.get_token() 1607db96d56Sopenharmony_ci while tok: 1617db96d56Sopenharmony_ci ret.append(tok) 1627db96d56Sopenharmony_ci tok = lex.get_token() 1637db96d56Sopenharmony_ci return ret 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci @mock.patch('sys.stdin', io.StringIO()) 1667db96d56Sopenharmony_ci def testSplitNoneDeprecation(self): 1677db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 1687db96d56Sopenharmony_ci shlex.split(None) 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci def testSplitPosix(self): 1717db96d56Sopenharmony_ci """Test data splitting with posix parser""" 1727db96d56Sopenharmony_ci self.splitTest(self.posix_data, comments=True) 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci def testCompat(self): 1757db96d56Sopenharmony_ci """Test compatibility interface""" 1767db96d56Sopenharmony_ci for i in range(len(self.data)): 1777db96d56Sopenharmony_ci l = self.oldSplit(self.data[i][0]) 1787db96d56Sopenharmony_ci self.assertEqual(l, self.data[i][1:], 1797db96d56Sopenharmony_ci "%s: %s != %s" % 1807db96d56Sopenharmony_ci (self.data[i][0], l, self.data[i][1:])) 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci def testSyntaxSplitAmpersandAndPipe(self): 1837db96d56Sopenharmony_ci """Test handling of syntax splitting of &, |""" 1847db96d56Sopenharmony_ci # Could take these forms: &&, &, |&, ;&, ;;& 1857db96d56Sopenharmony_ci # of course, the same applies to | and || 1867db96d56Sopenharmony_ci # these should all parse to the same output 1877db96d56Sopenharmony_ci for delimiter in ('&&', '&', '|&', ';&', ';;&', 1887db96d56Sopenharmony_ci '||', '|', '&|', ';|', ';;|'): 1897db96d56Sopenharmony_ci src = ['echo hi %s echo bye' % delimiter, 1907db96d56Sopenharmony_ci 'echo hi%secho bye' % delimiter] 1917db96d56Sopenharmony_ci ref = ['echo', 'hi', delimiter, 'echo', 'bye'] 1927db96d56Sopenharmony_ci for ss, ws in itertools.product(src, (False, True)): 1937db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 1947db96d56Sopenharmony_ci s.whitespace_split = ws 1957db96d56Sopenharmony_ci result = list(s) 1967db96d56Sopenharmony_ci self.assertEqual(ref, result, 1977db96d56Sopenharmony_ci "While splitting '%s' [ws=%s]" % (ss, ws)) 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci def testSyntaxSplitSemicolon(self): 2007db96d56Sopenharmony_ci """Test handling of syntax splitting of ;""" 2017db96d56Sopenharmony_ci # Could take these forms: ;, ;;, ;&, ;;& 2027db96d56Sopenharmony_ci # these should all parse to the same output 2037db96d56Sopenharmony_ci for delimiter in (';', ';;', ';&', ';;&'): 2047db96d56Sopenharmony_ci src = ['echo hi %s echo bye' % delimiter, 2057db96d56Sopenharmony_ci 'echo hi%s echo bye' % delimiter, 2067db96d56Sopenharmony_ci 'echo hi%secho bye' % delimiter] 2077db96d56Sopenharmony_ci ref = ['echo', 'hi', delimiter, 'echo', 'bye'] 2087db96d56Sopenharmony_ci for ss, ws in itertools.product(src, (False, True)): 2097db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 2107db96d56Sopenharmony_ci s.whitespace_split = ws 2117db96d56Sopenharmony_ci result = list(s) 2127db96d56Sopenharmony_ci self.assertEqual(ref, result, 2137db96d56Sopenharmony_ci "While splitting '%s' [ws=%s]" % (ss, ws)) 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci def testSyntaxSplitRedirect(self): 2167db96d56Sopenharmony_ci """Test handling of syntax splitting of >""" 2177db96d56Sopenharmony_ci # of course, the same applies to <, | 2187db96d56Sopenharmony_ci # these should all parse to the same output 2197db96d56Sopenharmony_ci for delimiter in ('<', '|'): 2207db96d56Sopenharmony_ci src = ['echo hi %s out' % delimiter, 2217db96d56Sopenharmony_ci 'echo hi%s out' % delimiter, 2227db96d56Sopenharmony_ci 'echo hi%sout' % delimiter] 2237db96d56Sopenharmony_ci ref = ['echo', 'hi', delimiter, 'out'] 2247db96d56Sopenharmony_ci for ss, ws in itertools.product(src, (False, True)): 2257db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 2267db96d56Sopenharmony_ci result = list(s) 2277db96d56Sopenharmony_ci self.assertEqual(ref, result, 2287db96d56Sopenharmony_ci "While splitting '%s' [ws=%s]" % (ss, ws)) 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci def testSyntaxSplitParen(self): 2317db96d56Sopenharmony_ci """Test handling of syntax splitting of ()""" 2327db96d56Sopenharmony_ci # these should all parse to the same output 2337db96d56Sopenharmony_ci src = ['( echo hi )', 2347db96d56Sopenharmony_ci '(echo hi)'] 2357db96d56Sopenharmony_ci ref = ['(', 'echo', 'hi', ')'] 2367db96d56Sopenharmony_ci for ss, ws in itertools.product(src, (False, True)): 2377db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 2387db96d56Sopenharmony_ci s.whitespace_split = ws 2397db96d56Sopenharmony_ci result = list(s) 2407db96d56Sopenharmony_ci self.assertEqual(ref, result, 2417db96d56Sopenharmony_ci "While splitting '%s' [ws=%s]" % (ss, ws)) 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci def testSyntaxSplitCustom(self): 2447db96d56Sopenharmony_ci """Test handling of syntax splitting with custom chars""" 2457db96d56Sopenharmony_ci ss = "~/a&&b-c --color=auto||d *.py?" 2467db96d56Sopenharmony_ci ref = ['~/a', '&', '&', 'b-c', '--color=auto', '||', 'd', '*.py?'] 2477db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars="|") 2487db96d56Sopenharmony_ci result = list(s) 2497db96d56Sopenharmony_ci self.assertEqual(ref, result, "While splitting '%s' [ws=False]" % ss) 2507db96d56Sopenharmony_ci ref = ['~/a&&b-c', '--color=auto', '||', 'd', '*.py?'] 2517db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars="|") 2527db96d56Sopenharmony_ci s.whitespace_split = True 2537db96d56Sopenharmony_ci result = list(s) 2547db96d56Sopenharmony_ci self.assertEqual(ref, result, "While splitting '%s' [ws=True]" % ss) 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci def testTokenTypes(self): 2577db96d56Sopenharmony_ci """Test that tokens are split with types as expected.""" 2587db96d56Sopenharmony_ci for source, expected in ( 2597db96d56Sopenharmony_ci ('a && b || c', 2607db96d56Sopenharmony_ci [('a', 'a'), ('&&', 'c'), ('b', 'a'), 2617db96d56Sopenharmony_ci ('||', 'c'), ('c', 'a')]), 2627db96d56Sopenharmony_ci ): 2637db96d56Sopenharmony_ci s = shlex.shlex(source, punctuation_chars=True) 2647db96d56Sopenharmony_ci observed = [] 2657db96d56Sopenharmony_ci while True: 2667db96d56Sopenharmony_ci t = s.get_token() 2677db96d56Sopenharmony_ci if t == s.eof: 2687db96d56Sopenharmony_ci break 2697db96d56Sopenharmony_ci if t[0] in s.punctuation_chars: 2707db96d56Sopenharmony_ci tt = 'c' 2717db96d56Sopenharmony_ci else: 2727db96d56Sopenharmony_ci tt = 'a' 2737db96d56Sopenharmony_ci observed.append((t, tt)) 2747db96d56Sopenharmony_ci self.assertEqual(observed, expected) 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci def testPunctuationInWordChars(self): 2777db96d56Sopenharmony_ci """Test that any punctuation chars are removed from wordchars""" 2787db96d56Sopenharmony_ci s = shlex.shlex('a_b__c', punctuation_chars='_') 2797db96d56Sopenharmony_ci self.assertNotIn('_', s.wordchars) 2807db96d56Sopenharmony_ci self.assertEqual(list(s), ['a', '_', 'b', '__', 'c']) 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci def testPunctuationWithWhitespaceSplit(self): 2837db96d56Sopenharmony_ci """Test that with whitespace_split, behaviour is as expected""" 2847db96d56Sopenharmony_ci s = shlex.shlex('a && b || c', punctuation_chars='&') 2857db96d56Sopenharmony_ci # whitespace_split is False, so splitting will be based on 2867db96d56Sopenharmony_ci # punctuation_chars 2877db96d56Sopenharmony_ci self.assertEqual(list(s), ['a', '&&', 'b', '|', '|', 'c']) 2887db96d56Sopenharmony_ci s = shlex.shlex('a && b || c', punctuation_chars='&') 2897db96d56Sopenharmony_ci s.whitespace_split = True 2907db96d56Sopenharmony_ci # whitespace_split is True, so splitting will be based on 2917db96d56Sopenharmony_ci # white space 2927db96d56Sopenharmony_ci self.assertEqual(list(s), ['a', '&&', 'b', '||', 'c']) 2937db96d56Sopenharmony_ci 2947db96d56Sopenharmony_ci def testPunctuationWithPosix(self): 2957db96d56Sopenharmony_ci """Test that punctuation_chars and posix behave correctly together.""" 2967db96d56Sopenharmony_ci # see Issue #29132 2977db96d56Sopenharmony_ci s = shlex.shlex('f >"abc"', posix=True, punctuation_chars=True) 2987db96d56Sopenharmony_ci self.assertEqual(list(s), ['f', '>', 'abc']) 2997db96d56Sopenharmony_ci s = shlex.shlex('f >\\"abc\\"', posix=True, punctuation_chars=True) 3007db96d56Sopenharmony_ci self.assertEqual(list(s), ['f', '>', '"abc"']) 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ci def testEmptyStringHandling(self): 3037db96d56Sopenharmony_ci """Test that parsing of empty strings is correctly handled.""" 3047db96d56Sopenharmony_ci # see Issue #21999 3057db96d56Sopenharmony_ci expected = ['', ')', 'abc'] 3067db96d56Sopenharmony_ci for punct in (False, True): 3077db96d56Sopenharmony_ci s = shlex.shlex("'')abc", posix=True, punctuation_chars=punct) 3087db96d56Sopenharmony_ci slist = list(s) 3097db96d56Sopenharmony_ci self.assertEqual(slist, expected) 3107db96d56Sopenharmony_ci expected = ["''", ')', 'abc'] 3117db96d56Sopenharmony_ci s = shlex.shlex("'')abc", punctuation_chars=True) 3127db96d56Sopenharmony_ci self.assertEqual(list(s), expected) 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ci def testUnicodeHandling(self): 3157db96d56Sopenharmony_ci """Test punctuation_chars and whitespace_split handle unicode.""" 3167db96d56Sopenharmony_ci ss = "\u2119\u01b4\u2602\u210c\u00f8\u1f24" 3177db96d56Sopenharmony_ci # Should be parsed as one complete token (whitespace_split=True). 3187db96d56Sopenharmony_ci ref = ['\u2119\u01b4\u2602\u210c\u00f8\u1f24'] 3197db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 3207db96d56Sopenharmony_ci s.whitespace_split = True 3217db96d56Sopenharmony_ci self.assertEqual(list(s), ref) 3227db96d56Sopenharmony_ci # Without whitespace_split, uses wordchars and splits on all. 3237db96d56Sopenharmony_ci ref = ['\u2119', '\u01b4', '\u2602', '\u210c', '\u00f8', '\u1f24'] 3247db96d56Sopenharmony_ci s = shlex.shlex(ss, punctuation_chars=True) 3257db96d56Sopenharmony_ci self.assertEqual(list(s), ref) 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_ci def testQuote(self): 3287db96d56Sopenharmony_ci safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./' 3297db96d56Sopenharmony_ci unicode_sample = '\xe9\xe0\xdf' # e + acute accent, a + grave, sharp s 3307db96d56Sopenharmony_ci unsafe = '"`$\\!' + unicode_sample 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci self.assertEqual(shlex.quote(''), "''") 3337db96d56Sopenharmony_ci self.assertEqual(shlex.quote(safeunquoted), safeunquoted) 3347db96d56Sopenharmony_ci self.assertEqual(shlex.quote('test file name'), "'test file name'") 3357db96d56Sopenharmony_ci for u in unsafe: 3367db96d56Sopenharmony_ci self.assertEqual(shlex.quote('test%sname' % u), 3377db96d56Sopenharmony_ci "'test%sname'" % u) 3387db96d56Sopenharmony_ci for u in unsafe: 3397db96d56Sopenharmony_ci self.assertEqual(shlex.quote("test%s'name'" % u), 3407db96d56Sopenharmony_ci "'test%s'\"'\"'name'\"'\"''" % u) 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci def testJoin(self): 3437db96d56Sopenharmony_ci for split_command, command in [ 3447db96d56Sopenharmony_ci (['a ', 'b'], "'a ' b"), 3457db96d56Sopenharmony_ci (['a', ' b'], "a ' b'"), 3467db96d56Sopenharmony_ci (['a', ' ', 'b'], "a ' ' b"), 3477db96d56Sopenharmony_ci (['"a', 'b"'], '\'"a\' \'b"\''), 3487db96d56Sopenharmony_ci ]: 3497db96d56Sopenharmony_ci with self.subTest(command=command): 3507db96d56Sopenharmony_ci joined = shlex.join(split_command) 3517db96d56Sopenharmony_ci self.assertEqual(joined, command) 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci def testJoinRoundtrip(self): 3547db96d56Sopenharmony_ci all_data = self.data + self.posix_data 3557db96d56Sopenharmony_ci for command, *split_command in all_data: 3567db96d56Sopenharmony_ci with self.subTest(command=command): 3577db96d56Sopenharmony_ci joined = shlex.join(split_command) 3587db96d56Sopenharmony_ci resplit = shlex.split(joined) 3597db96d56Sopenharmony_ci self.assertEqual(split_command, resplit) 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci def testPunctuationCharsReadOnly(self): 3627db96d56Sopenharmony_ci punctuation_chars = "/|$%^" 3637db96d56Sopenharmony_ci shlex_instance = shlex.shlex(punctuation_chars=punctuation_chars) 3647db96d56Sopenharmony_ci self.assertEqual(shlex_instance.punctuation_chars, punctuation_chars) 3657db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 3667db96d56Sopenharmony_ci shlex_instance.punctuation_chars = False 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ci# Allow this test to be used with old shlex.py 3707db96d56Sopenharmony_ciif not getattr(shlex, "split", None): 3717db96d56Sopenharmony_ci for methname in dir(ShlexTest): 3727db96d56Sopenharmony_ci if methname.startswith("test") and methname != "testCompat": 3737db96d56Sopenharmony_ci delattr(ShlexTest, methname) 3747db96d56Sopenharmony_ci 3757db96d56Sopenharmony_ciif __name__ == "__main__": 3767db96d56Sopenharmony_ci unittest.main() 377