mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	
		
			
	
	
		
			262 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			262 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import unittest | ||
|  | import sys | ||
|  | from collections import namedtuple | ||
|  | from test.support import import_helper | ||
|  | 
 | ||
|  | _testcapi = import_helper.import_module('_testcapi') | ||
|  | _testlimitedcapi = import_helper.import_module('_testlimitedcapi') | ||
|  | 
 | ||
|  | NULL = None | ||
|  | PY_SSIZE_T_MIN = _testcapi.PY_SSIZE_T_MIN | ||
|  | PY_SSIZE_T_MAX = _testcapi.PY_SSIZE_T_MAX | ||
|  | 
 | ||
|  | class TupleSubclass(tuple): | ||
|  |     pass | ||
|  | 
 | ||
|  | 
 | ||
|  | class CAPITest(unittest.TestCase): | ||
|  |     def test_check(self): | ||
|  |         # Test PyTuple_Check() | ||
|  |         check = _testlimitedcapi.tuple_check | ||
|  | 
 | ||
|  |         self.assertTrue(check((1, 2))) | ||
|  |         self.assertTrue(check(())) | ||
|  |         self.assertTrue(check(TupleSubclass((1, 2)))) | ||
|  |         self.assertFalse(check({1: 2})) | ||
|  |         self.assertFalse(check([1, 2])) | ||
|  |         self.assertFalse(check(42)) | ||
|  |         self.assertFalse(check(object())) | ||
|  | 
 | ||
|  |         # CRASHES check(NULL) | ||
|  | 
 | ||
|  |     def test_tuple_checkexact(self): | ||
|  |         # Test PyTuple_CheckExact() | ||
|  |         check = _testlimitedcapi.tuple_checkexact | ||
|  | 
 | ||
|  |         self.assertTrue(check((1, 2))) | ||
|  |         self.assertTrue(check(())) | ||
|  |         self.assertFalse(check(TupleSubclass((1, 2)))) | ||
|  |         self.assertFalse(check({1: 2})) | ||
|  |         self.assertFalse(check([1, 2])) | ||
|  |         self.assertFalse(check(42)) | ||
|  |         self.assertFalse(check(object())) | ||
|  | 
 | ||
|  |         # CRASHES check(NULL) | ||
|  | 
 | ||
|  |     def test_tuple_new(self): | ||
|  |         # Test PyTuple_New() | ||
|  |         tuple_new = _testlimitedcapi.tuple_new | ||
|  |         size = _testlimitedcapi.tuple_size | ||
|  |         checknull = _testcapi._check_tuple_item_is_NULL | ||
|  | 
 | ||
|  |         tup1 = tuple_new(0) | ||
|  |         self.assertEqual(tup1, ()) | ||
|  |         self.assertEqual(size(tup1), 0) | ||
|  |         self.assertIs(type(tup1), tuple) | ||
|  |         tup2 = tuple_new(1) | ||
|  |         self.assertIs(type(tup2), tuple) | ||
|  |         self.assertEqual(size(tup2), 1) | ||
|  |         self.assertIsNot(tup2, tup1) | ||
|  |         self.assertTrue(checknull(tup2, 0)) | ||
|  | 
 | ||
|  |         self.assertRaises(SystemError, tuple_new, -1) | ||
|  |         self.assertRaises(SystemError, tuple_new, PY_SSIZE_T_MIN) | ||
|  |         self.assertRaises(MemoryError, tuple_new, PY_SSIZE_T_MAX) | ||
|  | 
 | ||
|  |     def test_tuple_pack(self): | ||
|  |         # Test PyTuple_Pack() | ||
|  |         pack = _testlimitedcapi.tuple_pack | ||
|  | 
 | ||
|  |         self.assertEqual(pack(0), ()) | ||
|  |         self.assertEqual(pack(1, [1]), ([1],)) | ||
|  |         self.assertEqual(pack(2, [1], [2]), ([1], [2])) | ||
|  | 
 | ||
|  |         self.assertRaises(SystemError, pack, PY_SSIZE_T_MIN) | ||
|  |         self.assertRaises(SystemError, pack, -1) | ||
|  |         self.assertRaises(MemoryError, pack, PY_SSIZE_T_MAX) | ||
|  | 
 | ||
|  |         # CRASHES pack(1, NULL) | ||
|  |         # CRASHES pack(2, [1]) | ||
|  | 
 | ||
|  |     def test_tuple_size(self): | ||
|  |         # Test PyTuple_Size() | ||
|  |         size = _testlimitedcapi.tuple_size | ||
|  | 
 | ||
|  |         self.assertEqual(size(()), 0) | ||
|  |         self.assertEqual(size((1, 2)), 2) | ||
|  |         self.assertEqual(size(TupleSubclass((1, 2))), 2) | ||
|  | 
 | ||
|  |         self.assertRaises(SystemError, size, []) | ||
|  |         self.assertRaises(SystemError, size, 42) | ||
|  |         self.assertRaises(SystemError, size, object()) | ||
|  | 
 | ||
|  |         # CRASHES size(NULL) | ||
|  | 
 | ||
|  |     def test_tuple_get_size(self): | ||
|  |         # Test PyTuple_GET_SIZE() | ||
|  |         size = _testcapi.tuple_get_size | ||
|  | 
 | ||
|  |         self.assertEqual(size(()), 0) | ||
|  |         self.assertEqual(size((1, 2)), 2) | ||
|  |         self.assertEqual(size(TupleSubclass((1, 2))), 2) | ||
|  | 
 | ||
|  |     def test_tuple_getitem(self): | ||
|  |         # Test PyTuple_GetItem() | ||
|  |         getitem = _testlimitedcapi.tuple_getitem | ||
|  | 
 | ||
|  |         tup = ([1], [2], [3]) | ||
|  |         self.assertEqual(getitem(tup, 0), [1]) | ||
|  |         self.assertEqual(getitem(tup, 2), [3]) | ||
|  | 
 | ||
|  |         tup2 = TupleSubclass(([1], [2], [3])) | ||
|  |         self.assertEqual(getitem(tup2, 0), [1]) | ||
|  |         self.assertEqual(getitem(tup2, 2), [3]) | ||
|  | 
 | ||
|  |         self.assertRaises(IndexError, getitem, tup, PY_SSIZE_T_MIN) | ||
|  |         self.assertRaises(IndexError, getitem, tup, -1) | ||
|  |         self.assertRaises(IndexError, getitem, tup, len(tup)) | ||
|  |         self.assertRaises(IndexError, getitem, tup, PY_SSIZE_T_MAX) | ||
|  |         self.assertRaises(SystemError, getitem, [1, 2, 3], 1) | ||
|  |         self.assertRaises(SystemError, getitem, 42, 1) | ||
|  | 
 | ||
|  |         # CRASHES getitem(NULL, 0) | ||
|  | 
 | ||
|  |     def test_tuple_get_item(self): | ||
|  |         # Test PyTuple_GET_ITEM() | ||
|  |         get_item = _testcapi.tuple_get_item | ||
|  | 
 | ||
|  |         tup = ([1], [2], [3]) | ||
|  |         self.assertEqual(get_item(tup, 0), [1]) | ||
|  |         self.assertEqual(get_item(tup, 2), [3]) | ||
|  | 
 | ||
|  |         tup2 = TupleSubclass(([1], [2], [3])) | ||
|  |         self.assertEqual(get_item(tup2, 0), [1]) | ||
|  |         self.assertEqual(get_item(tup2, 2), [3]) | ||
|  | 
 | ||
|  |         # CRASHES get_item(NULL, 0) | ||
|  | 
 | ||
|  |     def test_tuple_getslice(self): | ||
|  |         # Test PyTuple_GetSlice() | ||
|  |         getslice = _testlimitedcapi.tuple_getslice | ||
|  | 
 | ||
|  |         # empty | ||
|  |         tup = ([1], [2], [3]) | ||
|  |         self.assertEqual(getslice(tup, PY_SSIZE_T_MIN, 0), ()) | ||
|  |         self.assertEqual(getslice(tup, -1, 0), ()) | ||
|  |         self.assertEqual(getslice(tup, 3, PY_SSIZE_T_MAX), ()) | ||
|  |         self.assertEqual(getslice(tup, 1, 1), ()) | ||
|  |         self.assertEqual(getslice(tup, 2, 1), ()) | ||
|  |         tup = TupleSubclass(([1], [2], [3])) | ||
|  |         self.assertEqual(getslice(tup, PY_SSIZE_T_MIN, 0), ()) | ||
|  |         self.assertEqual(getslice(tup, -1, 0), ()) | ||
|  |         self.assertEqual(getslice(tup, 3, PY_SSIZE_T_MAX), ()) | ||
|  |         self.assertEqual(getslice(tup, 1, 1), ()) | ||
|  |         self.assertEqual(getslice(tup, 2, 1), ()) | ||
|  | 
 | ||
|  |         # slice | ||
|  |         tup = ([1], [2], [3], [4]) | ||
|  |         self.assertEqual(getslice(tup, 1, 3), ([2], [3])) | ||
|  |         tup = TupleSubclass(([1], [2], [3], [4])) | ||
|  |         self.assertEqual(getslice(tup, 1, 3), ([2], [3])) | ||
|  | 
 | ||
|  |         # whole | ||
|  |         tup = ([1], [2], [3]) | ||
|  |         self.assertEqual(getslice(tup, 0, 3), tup) | ||
|  |         self.assertEqual(getslice(tup, 0, 100), tup) | ||
|  |         self.assertEqual(getslice(tup, -100, 100), tup) | ||
|  |         tup = TupleSubclass(([1], [2], [3])) | ||
|  |         self.assertEqual(getslice(tup, 0, 3), tup) | ||
|  |         self.assertEqual(getslice(tup, 0, 100), tup) | ||
|  |         self.assertEqual(getslice(tup, -100, 100), tup) | ||
|  | 
 | ||
|  |         self.assertRaises(SystemError, getslice, [[1], [2], [3]], 0, 0) | ||
|  |         self.assertRaises(SystemError, getslice, 42, 0, 0) | ||
|  | 
 | ||
|  |         # CRASHES getslice(NULL, 0, 0) | ||
|  | 
 | ||
|  |     def test_tuple_setitem(self): | ||
|  |         # Test PyTuple_SetItem() | ||
|  |         setitem = _testlimitedcapi.tuple_setitem | ||
|  |         checknull = _testcapi._check_tuple_item_is_NULL | ||
|  | 
 | ||
|  |         tup = ([1], [2]) | ||
|  |         self.assertEqual(setitem(tup, 0, []), ([], [2])) | ||
|  |         self.assertEqual(setitem(tup, 1, []), ([1], [])) | ||
|  | 
 | ||
|  |         tup2 = setitem(tup, 1, NULL) | ||
|  |         self.assertTrue(checknull(tup2, 1)) | ||
|  | 
 | ||
|  |         tup2 = TupleSubclass(([1], [2])) | ||
|  |         self.assertRaises(SystemError, setitem, tup2, 0, []) | ||
|  | 
 | ||
|  |         self.assertRaises(IndexError, setitem, tup, PY_SSIZE_T_MIN, []) | ||
|  |         self.assertRaises(IndexError, setitem, tup, -1, []) | ||
|  |         self.assertRaises(IndexError, setitem, tup, len(tup), []) | ||
|  |         self.assertRaises(IndexError, setitem, tup, PY_SSIZE_T_MAX, []) | ||
|  |         self.assertRaises(SystemError, setitem, [1], 0, []) | ||
|  |         self.assertRaises(SystemError, setitem, 42, 0, []) | ||
|  | 
 | ||
|  |         # CRASHES setitem(NULL, 0, []) | ||
|  | 
 | ||
|  |     def test_tuple_set_item(self): | ||
|  |         # Test PyTuple_SET_ITEM() | ||
|  |         set_item = _testcapi.tuple_set_item | ||
|  |         checknull = _testcapi._check_tuple_item_is_NULL | ||
|  | 
 | ||
|  |         tup = ([1], [2]) | ||
|  |         self.assertEqual(set_item(tup, 0, []), ([], [2])) | ||
|  |         self.assertEqual(set_item(tup, 1, []), ([1], [])) | ||
|  | 
 | ||
|  |         tup2 = set_item(tup, 1, NULL) | ||
|  |         self.assertTrue(checknull(tup2, 1)) | ||
|  | 
 | ||
|  |         tup2 = TupleSubclass(([1], [2])) | ||
|  |         self.assertIs(set_item(tup2, 0, []), tup2) | ||
|  |         self.assertEqual(tup2, ([], [2])) | ||
|  | 
 | ||
|  |         # CRASHES set_item(tup, -1, []) | ||
|  |         # CRASHES set_item(tup, len(tup), []) | ||
|  |         # CRASHES set_item([1], 0, []) | ||
|  |         # CRASHES set_item(NULL, 0, []) | ||
|  | 
 | ||
|  |     def test__tuple_resize(self): | ||
|  |         # Test _PyTuple_Resize() | ||
|  |         resize = _testcapi._tuple_resize | ||
|  |         checknull = _testcapi._check_tuple_item_is_NULL | ||
|  | 
 | ||
|  |         a = () | ||
|  |         b = resize(a, 0, False) | ||
|  |         self.assertEqual(len(a), 0) | ||
|  |         self.assertEqual(len(b), 0) | ||
|  |         b = resize(a, 2, False) | ||
|  |         self.assertEqual(len(a), 0) | ||
|  |         self.assertEqual(len(b), 2) | ||
|  |         self.assertTrue(checknull(b, 0)) | ||
|  |         self.assertTrue(checknull(b, 1)) | ||
|  | 
 | ||
|  |         a = ([1], [2], [3]) | ||
|  |         b = resize(a, 3) | ||
|  |         self.assertEqual(b, a) | ||
|  |         b = resize(a, 2) | ||
|  |         self.assertEqual(b, a[:2]) | ||
|  |         b = resize(a, 5) | ||
|  |         self.assertEqual(len(b), 5) | ||
|  |         self.assertEqual(b[:3], a) | ||
|  |         self.assertTrue(checknull(b, 3)) | ||
|  |         self.assertTrue(checknull(b, 4)) | ||
|  | 
 | ||
|  |         a = () | ||
|  |         self.assertRaises(MemoryError, resize, a, PY_SSIZE_T_MAX) | ||
|  |         self.assertRaises(SystemError, resize, a, -1) | ||
|  |         self.assertRaises(SystemError, resize, a, PY_SSIZE_T_MIN) | ||
|  |         # refcount > 1 | ||
|  |         a = (1, 2, 3) | ||
|  |         self.assertRaises(SystemError, resize, a, 3, False) | ||
|  |         self.assertRaises(SystemError, resize, a, 0, False) | ||
|  |         # non-tuple | ||
|  |         self.assertRaises(SystemError, resize, [1, 2, 3], 0, False) | ||
|  |         self.assertRaises(SystemError, resize, NULL, 0, False) | ||
|  | 
 | ||
|  | if __name__ == "__main__": | ||
|  |     unittest.main() |