1 #include "parts.h"
2 #include "util.h"
3
4
5 static PyObject *
tuple_get_size(PyObject * Py_UNUSED (module),PyObject * obj)6 tuple_get_size(PyObject *Py_UNUSED(module), PyObject *obj)
7 {
8 NULLABLE(obj);
9 RETURN_SIZE(PyTuple_GET_SIZE(obj));
10 }
11
12 static PyObject *
tuple_get_item(PyObject * Py_UNUSED (module),PyObject * args)13 tuple_get_item(PyObject *Py_UNUSED(module), PyObject *args)
14 {
15 PyObject *obj;
16 Py_ssize_t i;
17 if (!PyArg_ParseTuple(args, "On", &obj, &i)) {
18 return NULL;
19 }
20 NULLABLE(obj);
21 return Py_XNewRef(PyTuple_GET_ITEM(obj, i));
22 }
23
24 static PyObject *
tuple_copy(PyObject * tuple)25 tuple_copy(PyObject *tuple)
26 {
27 Py_ssize_t size = PyTuple_GET_SIZE(tuple);
28 PyObject *newtuple = PyTuple_New(size);
29 if (!newtuple) {
30 return NULL;
31 }
32 for (Py_ssize_t n = 0; n < size; n++) {
33 PyTuple_SET_ITEM(newtuple, n, Py_XNewRef(PyTuple_GET_ITEM(tuple, n)));
34 }
35 return newtuple;
36 }
37
38 static PyObject *
tuple_set_item(PyObject * Py_UNUSED (module),PyObject * args)39 tuple_set_item(PyObject *Py_UNUSED(module), PyObject *args)
40 {
41 PyObject *obj, *value, *newtuple;
42 Py_ssize_t i;
43 if (!PyArg_ParseTuple(args, "OnO", &obj, &i, &value)) {
44 return NULL;
45 }
46 NULLABLE(value);
47 if (PyTuple_CheckExact(obj)) {
48 newtuple = tuple_copy(obj);
49 if (!newtuple) {
50 return NULL;
51 }
52
53 PyObject *val = PyTuple_GET_ITEM(newtuple, i);
54 PyTuple_SET_ITEM(newtuple, i, Py_XNewRef(value));
55 Py_DECREF(val);
56 return newtuple;
57 }
58 else {
59 NULLABLE(obj);
60
61 PyObject *val = PyTuple_GET_ITEM(obj, i);
62 PyTuple_SET_ITEM(obj, i, Py_XNewRef(value));
63 Py_DECREF(val);
64 return Py_XNewRef(obj);
65 }
66 }
67
68 static PyObject *
_tuple_resize(PyObject * Py_UNUSED (module),PyObject * args)69 _tuple_resize(PyObject *Py_UNUSED(module), PyObject *args)
70 {
71 PyObject *tup;
72 Py_ssize_t newsize;
73 int new = 1;
74 if (!PyArg_ParseTuple(args, "On|p", &tup, &newsize, &new)) {
75 return NULL;
76 }
77 if (new) {
78 tup = tuple_copy(tup);
79 if (!tup) {
80 return NULL;
81 }
82 }
83 else {
84 NULLABLE(tup);
85 Py_XINCREF(tup);
86 }
87 int r = _PyTuple_Resize(&tup, newsize);
88 if (r == -1) {
89 assert(tup == NULL);
90 return NULL;
91 }
92 return tup;
93 }
94
95 static PyObject *
_check_tuple_item_is_NULL(PyObject * Py_UNUSED (module),PyObject * args)96 _check_tuple_item_is_NULL(PyObject *Py_UNUSED(module), PyObject *args)
97 {
98 PyObject *obj;
99 Py_ssize_t i;
100 if (!PyArg_ParseTuple(args, "On", &obj, &i)) {
101 return NULL;
102 }
103 return PyLong_FromLong(PyTuple_GET_ITEM(obj, i) == NULL);
104 }
105
106
107 static PyMethodDef test_methods[] = {
108 {"tuple_get_size", tuple_get_size, METH_O},
109 {"tuple_get_item", tuple_get_item, METH_VARARGS},
110 {"tuple_set_item", tuple_set_item, METH_VARARGS},
111 {"_tuple_resize", _tuple_resize, METH_VARARGS},
112 {"_check_tuple_item_is_NULL", _check_tuple_item_is_NULL, METH_VARARGS},
113 {NULL},
114 };
115
116 int
_PyTestCapi_Init_Tuple(PyObject * m)117 _PyTestCapi_Init_Tuple(PyObject *m)
118 {
119 if (PyModule_AddFunctions(m, test_methods) < 0) {
120 return -1;
121 }
122
123 return 0;
124 }
125