mirror of https://github.com/python/cpython
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()
|