Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersSequences.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* This helpers is used to work with sequence interfaces.
4
5*/
6
7// This file is included from another C file, help IDEs to still parse it on
8// its own.
9#ifdef __IDE_ONLY__
10#include "nuitka/prelude.h"
11#endif
12
13bool SEQUENCE_SET_ITEM(PyObject *sequence, Py_ssize_t index, PyObject *value) {
14 CHECK_OBJECT(sequence);
15 CHECK_OBJECT(value);
16
17 PySequenceMethods *tp_as_sequence = Py_TYPE(sequence)->tp_as_sequence;
18
19 if (tp_as_sequence != NULL && tp_as_sequence->sq_ass_item) {
20 if (index < 0) {
21 if (tp_as_sequence->sq_length) {
22 Py_ssize_t length = (*tp_as_sequence->sq_length)(sequence);
23
24 if (length < 0) {
25 return false;
26 }
27
28 index += length;
29 }
30 }
31
32 int res = tp_as_sequence->sq_ass_item(sequence, index, value);
33
34 if (unlikely(res == -1)) {
35 return false;
36 }
37
38 return true;
39 } else {
40 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("'%s' object does not support item assignment", sequence);
41 return false;
42 }
43}
44
45Py_ssize_t Nuitka_PyObject_Size(PyObject *sequence) {
46 CHECK_OBJECT(sequence);
47
48 PySequenceMethods *tp_as_sequence = Py_TYPE(sequence)->tp_as_sequence;
49
50 if (tp_as_sequence && tp_as_sequence->sq_length) {
51 return tp_as_sequence->sq_length(sequence);
52 }
53
54 return Nuitka_PyMapping_Size(sequence);
55}
56
57PyObject *Nuitka_Number_Index(PyObject *item) {
58 CHECK_OBJECT(item);
59
60#if PYTHON_VERSION < 0x300
61 if (PyInt_Check(item) || PyLong_Check(item))
62#else
63 if (PyLong_Check(item))
64#endif
65 {
66 Py_INCREF(item);
67 return item;
68 }
69
70 if (unlikely(!Nuitka_Index_Check(item))) {
71 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("'%s' object cannot be interpreted as an integer", item);
72 return NULL;
73 }
74
75 PyObject *result = Py_TYPE(item)->tp_as_number->nb_index(item);
76
77#if PYTHON_VERSION < 0x300
78 if (result == NULL || PyInt_CheckExact(result) || PyLong_CheckExact(result)) {
79 return result;
80 }
81#else
82 if (result == NULL || PyLong_CheckExact(result)) {
83 return result;
84 }
85#endif
86
87#if PYTHON_VERSION < 0x300
88 if (!PyInt_Check(result) && !PyLong_Check(result))
89#else
90 if (!PyLong_Check(result))
91#endif
92 {
93#if PYTHON_VERSION < 0x300
94 char const *message = "__index__ returned non-(int,long) (type %s)";
95#else
96 char const *message = "__index__ returned non-int (type %s)";
97#endif
98 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(message, result);
99
100 Py_DECREF(result);
101 return NULL;
102 }
103
104 return result;
105}
106
107#if PYTHON_VERSION >= 0x3a0
108PyObject *Nuitka_Number_IndexAsLong(PyObject *item) {
109 PyObject *result = Nuitka_Number_Index(item);
110
111 if (result != NULL) {
112 PyObject *converted_long = _PyLong_Copy((PyLongObject *)result);
113 Py_DECREF(result);
114
115 return converted_long;
116 } else {
117 return NULL;
118 }
119}
120#endif
121// Part of "Nuitka", an optimizing Python compiler that is compatible and
122// integrates with CPython, but also works on its own.
123//
124// Licensed under the Apache License, Version 2.0 (the "License");
125// you may not use this file except in compliance with the License.
126// You may obtain a copy of the License at
127//
128// http://www.apache.org/licenses/LICENSE-2.0
129//
130// Unless required by applicable law or agreed to in writing, software
131// distributed under the License is distributed on an "AS IS" BASIS,
132// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133// See the License for the specific language governing permissions and
134// limitations under the License.