|
32 | 32 | (b"&a=b", [(b'a', b'b')]),
|
33 | 33 | (b"a=a+b&b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
|
34 | 34 | (b"a=1&a=2", [(b'a', b'1'), (b'a', b'2')]),
|
35 |
| - (";", []), |
36 |
| - (";;", []), |
37 |
| - (";a=b", [('a', 'b')]), |
38 |
| - ("a=a+b;b=b+c", [('a', 'a b'), ('b', 'b c')]), |
39 |
| - ("a=1;a=2", [('a', '1'), ('a', '2')]), |
40 |
| - (b";", []), |
41 |
| - (b";;", []), |
42 |
| - (b";a=b", [(b'a', b'b')]), |
43 |
| - (b"a=a+b;b=b+c", [(b'a', b'a b'), (b'b', b'b c')]), |
44 |
| - (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]), |
| 35 | + (";a=b", [(';a', 'b')]), |
| 36 | + ("a=a+b;b=b+c", [('a', 'a b;b=b c')]), |
| 37 | + (b";a=b", [(b';a', b'b')]), |
| 38 | + (b"a=a+b;b=b+c", [(b'a', b'a b;b=b c')]), |
45 | 39 | ]
|
46 | 40 |
|
47 | 41 | # Each parse_qs testcase is a two-tuple that contains
|
|
68 | 62 | (b"&a=b", {b'a': [b'b']}),
|
69 | 63 | (b"a=a+b&b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
|
70 | 64 | (b"a=1&a=2", {b'a': [b'1', b'2']}),
|
71 |
| - (";", {}), |
72 |
| - (";;", {}), |
73 |
| - (";a=b", {'a': ['b']}), |
74 |
| - ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}), |
75 |
| - ("a=1;a=2", {'a': ['1', '2']}), |
76 |
| - (b";", {}), |
77 |
| - (b";;", {}), |
78 |
| - (b";a=b", {b'a': [b'b']}), |
79 |
| - (b"a=a+b;b=b+c", {b'a': [b'a b'], b'b': [b'b c']}), |
80 |
| - (b"a=1;a=2", {b'a': [b'1', b'2']}), |
| 65 | + (";a=b", {';a': ['b']}), |
| 66 | + ("a=a+b;b=b+c", {'a': ['a b;b=b c']}), |
| 67 | + (b";a=b", {b';a': [b'b']}), |
| 68 | + (b"a=a+b;b=b+c", {b'a':[ b'a b;b=b c']}), |
81 | 69 | ]
|
82 | 70 |
|
83 | 71 | class UrlParseTestCase(unittest.TestCase):
|
@@ -884,10 +872,46 @@ def test_parse_qsl_encoding(self):
|
884 | 872 | def test_parse_qsl_max_num_fields(self):
|
885 | 873 | with self.assertRaises(ValueError):
|
886 | 874 | urllib.parse.parse_qs('&'.join(['a=a']*11), max_num_fields=10)
|
887 |
| - with self.assertRaises(ValueError): |
888 |
| - urllib.parse.parse_qs(';'.join(['a=a']*11), max_num_fields=10) |
889 | 875 | urllib.parse.parse_qs('&'.join(['a=a']*10), max_num_fields=10)
|
890 | 876 |
|
| 877 | + def test_parse_qs_separator(self): |
| 878 | + parse_qs_semicolon_cases = [ |
| 879 | + (";", {}), |
| 880 | + (";;", {}), |
| 881 | + (";a=b", {'a': ['b']}), |
| 882 | + ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}), |
| 883 | + ("a=1;a=2", {'a': ['1', '2']}), |
| 884 | + (b";", {}), |
| 885 | + (b";;", {}), |
| 886 | + (b";a=b", {b'a': [b'b']}), |
| 887 | + (b"a=a+b;b=b+c", {b'a': [b'a b'], b'b': [b'b c']}), |
| 888 | + (b"a=1;a=2", {b'a': [b'1', b'2']}), |
| 889 | + ] |
| 890 | + for orig, expect in parse_qs_semicolon_cases: |
| 891 | + with self.subTest(f"Original: {orig!r}, Expected: {expect!r}"): |
| 892 | + result = urllib.parse.parse_qs(orig, separator=';') |
| 893 | + self.assertEqual(result, expect, "Error parsing %r" % orig) |
| 894 | + |
| 895 | + |
| 896 | + def test_parse_qsl_separator(self): |
| 897 | + parse_qsl_semicolon_cases = [ |
| 898 | + (";", []), |
| 899 | + (";;", []), |
| 900 | + (";a=b", [('a', 'b')]), |
| 901 | + ("a=a+b;b=b+c", [('a', 'a b'), ('b', 'b c')]), |
| 902 | + ("a=1;a=2", [('a', '1'), ('a', '2')]), |
| 903 | + (b";", []), |
| 904 | + (b";;", []), |
| 905 | + (b";a=b", [(b'a', b'b')]), |
| 906 | + (b"a=a+b;b=b+c", [(b'a', b'a b'), (b'b', b'b c')]), |
| 907 | + (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]), |
| 908 | + ] |
| 909 | + for orig, expect in parse_qsl_semicolon_cases: |
| 910 | + with self.subTest(f"Original: {orig!r}, Expected: {expect!r}"): |
| 911 | + result = urllib.parse.parse_qsl(orig, separator=';') |
| 912 | + self.assertEqual(result, expect, "Error parsing %r" % orig) |
| 913 | + |
| 914 | + |
891 | 915 | def test_urlencode_sequences(self):
|
892 | 916 | # Other tests incidentally urlencode things; test non-covered cases:
|
893 | 917 | # Sequence and object values.
|
|
0 commit comments