-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
(cherry picked from commit dbc1752) Co-authored-by: kalyanr <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Victor Stinner <[email protected]>
- Loading branch information
1 parent
b01063d
commit 625072f
Showing
4 changed files
with
496 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
import unittest | ||
import sys | ||
from collections import namedtuple | ||
from test.support import import_helper | ||
|
||
_testcapi = import_helper.import_module('_testcapi') | ||
_testlimitedcapi = _testcapi | ||
|
||
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() |
Oops, something went wrong.