|
1 | 1 | import unittest
|
2 | 2 | import math
|
| 3 | +import string |
3 | 4 | import sys
|
4 | 5 | from test import test_support
|
5 | 6 | # Skip this test if the _testcapi module isn't available.
|
6 |
| -test_support.import_module('_testcapi') |
| 7 | +_testcapi = test_support.import_module('_testcapi') |
7 | 8 | from _testcapi import getargs_keywords
|
8 | 9 | import warnings
|
9 | 10 |
|
@@ -799,12 +800,6 @@ def test_u_hash(self):
|
799 | 800 | self.assertRaises(TypeError, getargs_u_hash, None)
|
800 | 801 |
|
801 | 802 |
|
802 |
| -def test_main(): |
803 |
| - tests = [Signed_TestCase, Unsigned_TestCase, LongLong_TestCase, |
804 |
| - Tuple_TestCase, Keywords_TestCase, |
805 |
| - Bytes_TestCase, String_TestCase, Unicode_TestCase] |
806 |
| - test_support.run_unittest(*tests) |
807 |
| - |
808 | 803 | class Object_TestCase(unittest.TestCase):
|
809 | 804 | def test_S(self):
|
810 | 805 | from _testcapi import getargs_S
|
@@ -840,5 +835,142 @@ def test_U(self):
|
840 | 835 | self.assertRaises(TypeError, getargs_U, buffer(obj))
|
841 | 836 |
|
842 | 837 |
|
| 838 | +class SkipitemTest(unittest.TestCase): |
| 839 | + |
| 840 | + def test_skipitem(self): |
| 841 | + """ |
| 842 | + If this test failed, you probably added a new "format unit" |
| 843 | + in Python/getargs.c, but neglected to update our poor friend |
| 844 | + skipitem() in the same file. (If so, shame on you!) |
| 845 | +
|
| 846 | + With a few exceptions**, this function brute-force tests all |
| 847 | + printable ASCII*** characters (32 to 126 inclusive) as format units, |
| 848 | + checking to see that PyArg_ParseTupleAndKeywords() return consistent |
| 849 | + errors both when the unit is attempted to be used and when it is |
| 850 | + skipped. If the format unit doesn't exist, we'll get one of two |
| 851 | + specific error messages (one for used, one for skipped); if it does |
| 852 | + exist we *won't* get that error--we'll get either no error or some |
| 853 | + other error. If we get the specific "does not exist" error for one |
| 854 | + test and not for the other, there's a mismatch, and the test fails. |
| 855 | +
|
| 856 | + ** Some format units have special funny semantics and it would |
| 857 | + be difficult to accommodate them here. Since these are all |
| 858 | + well-established and properly skipped in skipitem() we can |
| 859 | + get away with not testing them--this test is really intended |
| 860 | + to catch *new* format units. |
| 861 | +
|
| 862 | + *** Python C source files must be ASCII. Therefore it's impossible |
| 863 | + to have non-ASCII format units. |
| 864 | +
|
| 865 | + """ |
| 866 | + empty_tuple = () |
| 867 | + tuple_1 = (0,) |
| 868 | + dict_b = {'b':1} |
| 869 | + keywords = ["a", "b"] |
| 870 | + |
| 871 | + for i in range(32, 127): |
| 872 | + c = chr(i) |
| 873 | + |
| 874 | + # skip parentheses, the error reporting is inconsistent about them |
| 875 | + # skip 'e', it's always a two-character code |
| 876 | + # skip '|', it doesn't represent arguments anyway |
| 877 | + if c in '()e|': |
| 878 | + continue |
| 879 | + |
| 880 | + # test the format unit when not skipped |
| 881 | + format = c + "i" |
| 882 | + try: |
| 883 | + _testcapi.parse_tuple_and_keywords(tuple_1, dict_b, |
| 884 | + format, keywords) |
| 885 | + when_not_skipped = False |
| 886 | + except TypeError as e: |
| 887 | + s = "argument 1 (impossible<bad format char>)" |
| 888 | + when_not_skipped = (str(e) == s) |
| 889 | + except RuntimeError: |
| 890 | + when_not_skipped = False |
| 891 | + |
| 892 | + # test the format unit when skipped |
| 893 | + optional_format = "|" + format |
| 894 | + try: |
| 895 | + _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b, |
| 896 | + optional_format, keywords) |
| 897 | + when_skipped = False |
| 898 | + except RuntimeError as e: |
| 899 | + s = "impossible<bad format char>: '{}'".format(format) |
| 900 | + when_skipped = (str(e) == s) |
| 901 | + |
| 902 | + message = ("test_skipitem_parity: " |
| 903 | + "detected mismatch between convertsimple and skipitem " |
| 904 | + "for format unit '{}' ({}), not skipped {}, skipped {}".format( |
| 905 | + c, i, when_skipped, when_not_skipped)) |
| 906 | + self.assertIs(when_skipped, when_not_skipped, message) |
| 907 | + |
| 908 | + def test_skipitem_with_suffix(self): |
| 909 | + parse = _testcapi.parse_tuple_and_keywords |
| 910 | + empty_tuple = () |
| 911 | + tuple_1 = (0,) |
| 912 | + dict_b = {'b':1} |
| 913 | + keywords = ["a", "b"] |
| 914 | + |
| 915 | + supported = ('s#', 's*', 'z#', 'z*', 'u#', 't#', 'w#', 'w*') |
| 916 | + for c in string.ascii_letters: |
| 917 | + for c2 in '#*': |
| 918 | + f = c + c2 |
| 919 | + optional_format = "|" + f + "i" |
| 920 | + if f in supported: |
| 921 | + parse(empty_tuple, dict_b, optional_format, keywords) |
| 922 | + else: |
| 923 | + with self.assertRaisesRegexp((RuntimeError, TypeError), |
| 924 | + 'impossible<bad format char>'): |
| 925 | + parse(empty_tuple, dict_b, optional_format, keywords) |
| 926 | + |
| 927 | + for c in map(chr, range(32, 128)): |
| 928 | + f = 'e' + c |
| 929 | + optional_format = "|" + f + "i" |
| 930 | + if c in 'st': |
| 931 | + parse(empty_tuple, dict_b, optional_format, keywords) |
| 932 | + else: |
| 933 | + with self.assertRaisesRegexp(RuntimeError, |
| 934 | + 'impossible<bad format char>'): |
| 935 | + parse(empty_tuple, dict_b, optional_format, keywords) |
| 936 | + |
| 937 | + |
| 938 | +class ParseTupleAndKeywords_Test(unittest.TestCase): |
| 939 | + |
| 940 | + def test_parse_tuple_and_keywords(self): |
| 941 | + # Test handling errors in the parse_tuple_and_keywords helper itself |
| 942 | + self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords, |
| 943 | + (), {}, 42, []) |
| 944 | + self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, |
| 945 | + (), {}, '', 42) |
| 946 | + self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, |
| 947 | + (), {}, '', [''] * 42) |
| 948 | + self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords, |
| 949 | + (), {}, '', [42]) |
| 950 | + |
| 951 | + def test_bad_use(self): |
| 952 | + # Test handling invalid format and keywords in |
| 953 | + # PyArg_ParseTupleAndKeywords() |
| 954 | + self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords, |
| 955 | + (1,), {}, '||O', ['a']) |
| 956 | + self.assertRaises(RuntimeError, _testcapi.parse_tuple_and_keywords, |
| 957 | + (1,), {}, '|O', ['a', 'b']) |
| 958 | + self.assertRaises(RuntimeError, _testcapi.parse_tuple_and_keywords, |
| 959 | + (1,), {}, '|OO', ['a']) |
| 960 | + |
| 961 | + |
| 962 | +class Test_testcapi(unittest.TestCase): |
| 963 | + locals().update((name, getattr(_testcapi, name)) |
| 964 | + for name in dir(_testcapi) |
| 965 | + if name.startswith('test_') and name.endswith('_code')) |
| 966 | + |
| 967 | + |
| 968 | +def test_main(): |
| 969 | + tests = [Signed_TestCase, Unsigned_TestCase, LongLong_TestCase, |
| 970 | + Tuple_TestCase, Keywords_TestCase, |
| 971 | + Bytes_TestCase, String_TestCase, Unicode_TestCase, |
| 972 | + SkipitemTest, ParseTupleAndKeywords_Test, Test_testcapi] |
| 973 | + test_support.run_unittest(*tests) |
| 974 | + |
843 | 975 | if __name__ == "__main__":
|
844 | 976 | test_main()
|
0 commit comments