Nuitka
The Python compiler
Loading...
Searching...
No Matches
tuples.h
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3#ifndef __NUITKA_HELPER_TUPLES_H__
4#define __NUITKA_HELPER_TUPLES_H__
5
6// Like PyTuple_SET_ITEM, but takes a reference to the item.
7#define PyTuple_SET_ITEM0(tuple, index, value) \
8 { \
9 PyObject *tmp = value; \
10 Py_INCREF(tmp); \
11 PyTuple_SET_ITEM(tuple, index, tmp); \
12 }
13
14// Like PyTuple_SET_ITEM, but takes a reference to the immortal value pre 3.12
15#if PYTHON_VERSION < 0x3c0
16#define PyTuple_SET_ITEM_IMMORTAL(tuple, index, value) PyTuple_SET_ITEM0(tuple, index, value)
17#else
18#define PyTuple_SET_ITEM_IMMORTAL(tuple, index, value) PyTuple_SET_ITEM(tuple, index, value)
19#endif
20
21#if PYTHON_VERSION >= 0x3a0 && !defined(_NUITKA_EXPERIMENTAL_DISABLE_FREELIST_ALL)
22#define NUITKA_TUPLE_HAS_FREELIST 1
23// Make empty tuple, size > 0
24extern PyObject *MAKE_TUPLE_EMPTY(PyThreadState *tstate, Py_ssize_t size);
25// Make empty tuple, size >= 0
26extern PyObject *MAKE_TUPLE_EMPTY_VAR(PyThreadState *tstate, Py_ssize_t size);
27#else
28#define NUITKA_TUPLE_HAS_FREELIST 0
29
30// Make empty tuple, size > 0
31#define MAKE_TUPLE_EMPTY(tstate, size) PyTuple_New(size)
32// Make empty tuple, size >= 0
33#define MAKE_TUPLE_EMPTY_VAR(tstate, size) PyTuple_New(size)
34#endif
35
36NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE(PyThreadState *tstate, PyObject *const *elements, Py_ssize_t size) {
37 assert(size > 0);
38 assert(elements != NULL);
39 CHECK_OBJECTS(elements, size);
40
41 PyObject *result = MAKE_TUPLE_EMPTY(tstate, size);
42
43 for (Py_ssize_t i = 0; i < size; i++) {
44 PyTuple_SET_ITEM0(result, i, elements[i]);
45 }
46
47 return result;
48}
49
50NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE_VAR(PyThreadState *tstate, PyObject *const *elements,
51 Py_ssize_t size) {
52 PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, size);
53
54 for (Py_ssize_t i = 0; i < size; i++) {
55 PyTuple_SET_ITEM0(result, i, elements[i]);
56 }
57
58 return result;
59}
60
61NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE1(PyThreadState *tstate, PyObject *element1) {
62 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 1);
63
64 PyTuple_SET_ITEM0(result, 0, element1);
65
66 return result;
67}
68
69NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE1_0(PyThreadState *tstate, PyObject *element1) {
70 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 1);
71
72 PyTuple_SET_ITEM(result, 0, element1);
73
74 return result;
75}
76
77NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE2(PyThreadState *tstate, PyObject *element1, PyObject *element2) {
78 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 2);
79
80 PyTuple_SET_ITEM0(result, 0, element1);
81 PyTuple_SET_ITEM0(result, 1, element2);
82
83 return result;
84}
85
86NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE2_0(PyThreadState *tstate, PyObject *element1, PyObject *element2) {
87 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 2);
88
89 PyTuple_SET_ITEM(result, 0, element1);
90 PyTuple_SET_ITEM(result, 1, element2);
91
92 return result;
93}
94
95NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE3(PyThreadState *tstate, PyObject *element1, PyObject *element2,
96 PyObject *element3) {
97 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 3);
98
99 PyTuple_SET_ITEM0(result, 0, element1);
100 PyTuple_SET_ITEM0(result, 1, element2);
101 PyTuple_SET_ITEM0(result, 2, element3);
102
103 return result;
104}
105
106NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE3_0(PyThreadState *tstate, PyObject *element1, PyObject *element2,
107 PyObject *element3) {
108 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 3);
109
110 PyTuple_SET_ITEM(result, 0, element1);
111 PyTuple_SET_ITEM(result, 1, element2);
112 PyTuple_SET_ITEM(result, 2, element3);
113
114 return result;
115}
116
117NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE4(PyThreadState *tstate, PyObject *element1, PyObject *element2,
118 PyObject *element3, PyObject *element4) {
119 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 4);
120
121 PyTuple_SET_ITEM0(result, 0, element1);
122 PyTuple_SET_ITEM0(result, 1, element2);
123 PyTuple_SET_ITEM0(result, 2, element3);
124 PyTuple_SET_ITEM0(result, 3, element4);
125
126 return result;
127}
128
129NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE4_0(PyThreadState *tstate, PyObject *element1, PyObject *element2,
130 PyObject *element3, PyObject *element4) {
131 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 4);
132
133 PyTuple_SET_ITEM(result, 0, element1);
134 PyTuple_SET_ITEM(result, 1, element2);
135 PyTuple_SET_ITEM(result, 2, element3);
136 PyTuple_SET_ITEM(result, 3, element4);
137
138 return result;
139}
140
141NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE5(PyThreadState *tstate, PyObject *element1, PyObject *element2,
142 PyObject *element3, PyObject *element4, PyObject *element5) {
143 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 5);
144
145 PyTuple_SET_ITEM0(result, 0, element1);
146 PyTuple_SET_ITEM0(result, 1, element2);
147 PyTuple_SET_ITEM0(result, 2, element3);
148 PyTuple_SET_ITEM0(result, 3, element4);
149 PyTuple_SET_ITEM0(result, 4, element5);
150
151 return result;
152}
153
154NUITKA_MAY_BE_UNUSED static PyObject *MAKE_TUPLE5_0(PyThreadState *tstate, PyObject *element1, PyObject *element2,
155 PyObject *element3, PyObject *element4, PyObject *element5) {
156 PyObject *result = MAKE_TUPLE_EMPTY(tstate, 5);
157
158 PyTuple_SET_ITEM(result, 0, element1);
159 PyTuple_SET_ITEM(result, 1, element2);
160 PyTuple_SET_ITEM(result, 2, element3);
161 PyTuple_SET_ITEM(result, 3, element4);
162 PyTuple_SET_ITEM(result, 4, element5);
163
164 return result;
165}
166
167// Make this new macro available for older Python too.
168#ifndef _PyTuple_ITEMS
169#define _PyTuple_ITEMS(op) (((PyTupleObject *)(op))->ob_item)
170#endif
171
172extern PyObject *TUPLE_CONCAT(PyThreadState *tstate, PyObject *tuple1, PyObject *tuple2);
173
174extern PyObject *TUPLE_COPY(PyThreadState *tstate, PyObject *tuple);
175
176#endif
177
178// Part of "Nuitka", an optimizing Python compiler that is compatible and
179// integrates with CPython, but also works on its own.
180//
181// Licensed under the GNU Affero General Public License, Version 3 (the "License");
182// you may not use this file except in compliance with the License.
183// You may obtain a copy of the License at
184//
185// http://www.gnu.org/licenses/agpl.txt
186//
187// Unless required by applicable law or agreed to in writing, software
188// distributed under the License is distributed on an "AS IS" BASIS,
189// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190// See the License for the specific language governing permissions and
191// limitations under the License.