3#ifndef __NUITKA_HELPER_ITERATORS_H__
4#define __NUITKA_HELPER_ITERATORS_H__
6#if PYTHON_VERSION >= 0x270
9extern iternextfunc default_iternext;
10extern void _initSlotIterNext(
void);
14NUITKA_MAY_BE_UNUSED
static inline bool HAS_ITERNEXT(PyObject *value) {
15#if PYTHON_VERSION < 0x300
16 if (!PyType_HasFeature(Py_TYPE(value), Py_TPFLAGS_HAVE_ITER)) {
21 iternextfunc tp_iternext = Py_TYPE(value)->tp_iternext;
23 if (tp_iternext == NULL) {
27#if PYTHON_VERSION >= 0x270
28 return tp_iternext != default_iternext;
38#if PYTHON_VERSION < 0x300
46NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_ITERATOR_INFALLIBLE(PyObject *iterated) {
47 CHECK_OBJECT(iterated);
49#if PYTHON_VERSION < 0x300
50 getiterfunc tp_iter = NULL;
51 if (PyType_HasFeature(Py_TYPE(iterated), Py_TPFLAGS_HAVE_ITER)) {
52 tp_iter = Py_TYPE(iterated)->tp_iter;
55 getiterfunc tp_iter = Py_TYPE(iterated)->tp_iter;
58 PyObject *result = (*tp_iter)(iterated);
60 assert(HAS_ITERNEXT(result));
64 assert(PySequence_Check(iterated));
71 result->it_seq = iterated;
73 Nuitka_GC_Track(result);
75 return (PyObject *)result;
79NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_ITERATOR(PyThreadState *tstate, PyObject *iterated) {
80 CHECK_OBJECT(iterated);
82#if _NUITKA_EXPERIMENTAL_DISABLE_ITERATOR_OPT
83 return PyObject_GetIter(iterated);
86#if PYTHON_VERSION < 0x300
87 getiterfunc tp_iter = NULL;
88 if (PyType_HasFeature(Py_TYPE(iterated), Py_TPFLAGS_HAVE_ITER)) {
89 tp_iter = Py_TYPE(iterated)->tp_iter;
92 getiterfunc tp_iter = Py_TYPE(iterated)->tp_iter;
96 PyObject *result = (*tp_iter)(iterated);
98 if (unlikely(result == NULL)) {
100 }
else if (unlikely(!HAS_ITERNEXT(result))) {
101 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
"iter() returned non-iterator of type '%s'", result);
109 }
else if (PySequence_Check(iterated)) {
113 result->it_index = 0;
115 result->it_seq = iterated;
117 Nuitka_GC_Track(result);
119 return (PyObject *)result;
121 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
"'%s' object is not iterable", iterated);
128#if PYTHON_VERSION >= 0x370
130NUITKA_MAY_BE_UNUSED
static PyObject *MAKE_UNPACK_ITERATOR(PyObject *iterated) {
131 CHECK_OBJECT(iterated);
133 getiterfunc tp_iter = Py_TYPE(iterated)->tp_iter;
136 PyObject *result = (*tp_iter)(iterated);
138 if (unlikely(result == NULL)) {
140 }
else if (unlikely(!HAS_ITERNEXT(result))) {
141 PyErr_Format(PyExc_TypeError,
"iter() returned non-iterator of type '%s'", Py_TYPE(result)->tp_name);
149 }
else if (PySequence_Check(iterated)) {
153 result->it_index = 0;
155 result->it_seq = iterated;
157 Nuitka_GC_Track(result);
159 return (PyObject *)result;
161 PyErr_Format(PyExc_TypeError,
"cannot unpack non-iterable %s object", Py_TYPE(iterated)->tp_name);
169NUITKA_MAY_BE_UNUSED
static PyObject *ITERATOR_NEXT_ITERATOR(PyObject *iterator) {
170 CHECK_OBJECT(iterator);
171 iternextfunc iternext = Py_TYPE(iterator)->tp_iternext;
172 assert(iternext != NULL);
174#if _NUITKA_EXPERIMENTAL_DISABLE_ITERATOR_OPT
175 return PyIter_Next(iterator);
177 PyObject *result = (*iternext)(iterator);
178 CHECK_OBJECT_X(result);
183NUITKA_MAY_BE_UNUSED
static PyObject *ITERATOR_NEXT(PyObject *iterator) {
184 CHECK_OBJECT(iterator);
186#if _NUITKA_EXPERIMENTAL_DISABLE_ITERATOR_OPT
187 return PyIter_Next(iterator);
189 iternextfunc iternext = Py_TYPE(iterator)->tp_iternext;
191 if (unlikely(iternext == NULL)) {
192 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
193#
if PYTHON_VERSION < 0x300 && defined(_NUITKA_FULL_COMPAT)
194 "%s object is not an iterator",
196 "'%s' object is not an iterator",
203 PyObject *result = (*iternext)(iterator);
205 CHECK_OBJECT_X(result);
211NUITKA_MAY_BE_UNUSED
static PyObject *BUILTIN_NEXT2(PyThreadState *tstate, PyObject *iterator,
212 PyObject *default_value) {
213 CHECK_OBJECT(iterator);
214 CHECK_OBJECT(default_value);
216 PyObject *result = (*Py_TYPE(iterator)->tp_iternext)(iterator);
218 if (unlikely(result == NULL)) {
219 bool stop_iteration_error = CHECK_AND_CLEAR_STOP_ITERATION_OCCURRED(tstate);
221 if (unlikely(stop_iteration_error ==
false)) {
225 Py_INCREF(default_value);
226 return default_value;
229 CHECK_OBJECT(result);
234NUITKA_MAY_BE_UNUSED
static PyObject *UNPACK_NEXT_INFALLIBLE(PyObject *iterator) {
235 CHECK_OBJECT(iterator);
236 assert(HAS_ITERNEXT(iterator));
238 PyObject *result = (*Py_TYPE(iterator)->tp_iternext)(iterator);
239 CHECK_OBJECT(result);
243#if PYTHON_VERSION < 0x350
244NUITKA_MAY_BE_UNUSED
static PyObject *UNPACK_NEXT(PyThreadState *tstate,
246 PyObject *iterator,
int seq_size_so_far)
248NUITKA_MAY_BE_UNUSED
static PyObject *UNPACK_NEXT(PyThreadState *tstate,
250 PyObject *iterator,
int seq_size_so_far,
int expected)
253 CHECK_OBJECT(iterator);
254 assert(HAS_ITERNEXT(iterator));
256 PyObject *result = (*Py_TYPE(iterator)->tp_iternext)(iterator);
258 if (unlikely(result == NULL)) {
259 bool had_stop_iteration =
true;
261 PyObject *error = GET_ERROR_OCCURRED(tstate);
264 if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, error, PyExc_StopIteration)) {
265 CLEAR_ERROR_OCCURRED(tstate);
267 had_stop_iteration =
false;
271 if (had_stop_iteration) {
272#if PYTHON_VERSION < 0x350
273 if (seq_size_so_far == 1) {
274 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_STR(tstate, exception_state, PyExc_ValueError,
275 "need more than 1 value to unpack");
277 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_FORMAT1(
278 tstate, exception_state, PyExc_ValueError,
"need more than %d values to unpack", seq_size_so_far);
281 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_FORMAT2(tstate, exception_state, PyExc_ValueError,
282 "not enough values to unpack (expected %d, got %d)",
283 expected, seq_size_so_far);
286 assert(HAS_ERROR_OCCURRED(tstate));
287 FETCH_ERROR_OCCURRED_STATE(tstate, exception_state);
293 CHECK_OBJECT(result);
298#if PYTHON_VERSION >= 0x350
300NUITKA_MAY_BE_UNUSED
static PyObject *UNPACK_NEXT_STARRED(PyThreadState *tstate,
302 PyObject *iterator,
int seq_size_so_far,
int expected) {
303 CHECK_OBJECT(iterator);
304 assert(HAS_ITERNEXT(iterator));
306 PyObject *result = (*Py_TYPE(iterator)->tp_iternext)(iterator);
308 if (unlikely(result == NULL)) {
309 FETCH_ERROR_OCCURRED_STATE(tstate, exception_state);
313 if (!HAS_EXCEPTION_STATE(exception_state) ||
314 EXCEPTION_STATE_MATCH_BOOL_SINGLE(tstate, exception_state, PyExc_StopIteration)) {
315 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_FORMAT2(
316 tstate, exception_state, PyExc_ValueError,
"not enough values to unpack (expected at least %d, got %d)",
317 expected, seq_size_so_far);
323 CHECK_OBJECT(result);
329NUITKA_MAY_BE_UNUSED
static bool UNPACK_ITERATOR_CHECK(PyThreadState *tstate,
331 PyObject *iterator,
int expected) {
332 PyObject *attempt = (*(Py_TYPE(iterator)->tp_iternext))(iterator);
334 if (likely(attempt == NULL)) {
335 PyObject *error = GET_ERROR_OCCURRED(tstate);
338 if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, error, PyExc_StopIteration)) {
339 CLEAR_ERROR_OCCURRED(tstate);
341 FETCH_ERROR_OCCURRED_STATE(tstate, exception_state);
350#if PYTHON_VERSION < 0x300
351 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_STR(tstate, exception_state, PyExc_ValueError,
352 "too many values to unpack");
354 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_FORMAT1(tstate, exception_state, PyExc_ValueError,
355 "too many values to unpack (expected %d)", expected);
Definition exceptions.h:712
Definition iterators.h:36