diff --git a/2021-10-13-142008-6609-cppcheck@0d043da76d00_memory_array/index.html b/2021-10-13-142008-6609-cppcheck@0d043da76d00_memory_array/index.html new file mode 100644 index 0000000..e45957c --- /dev/null +++ b/2021-10-13-142008-6609-cppcheck@0d043da76d00_memory_array/index.html @@ -0,0 +1,114 @@ + + + +
+ +User: | root@b6360d00b20a |
---|---|
Working Directory: | /rootdir |
Command Line: | make -j 2 |
Clang Version: | clang version 12.0.1 (Fedora 12.0.1-1.fc34) + |
Date: | Wed Oct 13 17:21:59 2021 |
Bug Type | Quantity | Display? |
All Bugs | 2 | |
Logic error | ||
---|---|---|
Potential unintended use of sizeof() on pointer type | 2 |
Bug Group | +Bug Type ▾ | +File | +Function/Method | +Line | +Path Length | ++ + |
Logic error | Potential unintended use of sizeof() on pointer type | abstract.h | PyVectorcall_Function | 80 | 1 | View Report | + +
Logic error | Potential unintended use of sizeof() on pointer type | abstract.h | PyVectorcall_Function | 80 | 1 | View Report | + +
File: | abstract.h |
Warning: | line 80, column 46 The code calls sizeof() on a pointer type. This can produce an unexpected result |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | #ifndef Py_CPYTHON_ABSTRACTOBJECT_H |
2 | # error "this header file must not be included directly" |
3 | #endif |
4 | |
5 | #ifdef __cplusplus |
6 | extern "C" { |
7 | #endif |
8 | |
9 | /* === Object Protocol ================================================== */ |
10 | |
11 | #ifdef PY_SSIZE_T_CLEAN |
12 | # define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT |
13 | #endif |
14 | |
15 | /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) |
16 | format to a Python dictionary ("kwargs" dict). |
17 | |
18 | The type of kwnames keys is not checked. The final function getting |
19 | arguments is responsible to check if all keys are strings, for example using |
20 | PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). |
21 | |
22 | Duplicate keys are merged using the last value. If duplicate keys must raise |
23 | an exception, the caller is responsible to implement an explicit keys on |
24 | kwnames. */ |
25 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyStack_AsDict( |
26 | PyObject *const *values, |
27 | PyObject *kwnames); |
28 | |
29 | /* Suggested size (number of positional arguments) for arrays of PyObject* |
30 | allocated on a C stack to avoid allocating memory on the heap memory. Such |
31 | array is used to pass positional arguments to call functions of the |
32 | PyObject_Vectorcall() family. |
33 | |
34 | The size is chosen to not abuse the C stack and so limit the risk of stack |
35 | overflow. The size is also chosen to allow using the small stack for most |
36 | function calls of the Python standard library. On 64-bit CPU, it allocates |
37 | 40 bytes on the stack. */ |
38 | #define _PY_FASTCALL_SMALL_STACK5 5 |
39 | |
40 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _Py_CheckFunctionResult( |
41 | PyThreadState *tstate, |
42 | PyObject *callable, |
43 | PyObject *result, |
44 | const char *where); |
45 | |
46 | /* === Vectorcall protocol (PEP 590) ============================= */ |
47 | |
48 | /* Call callable using tp_call. Arguments are like PyObject_Vectorcall() |
49 | or PyObject_FastCallDict() (both forms are supported), |
50 | except that nargs is plainly the number of arguments without flags. */ |
51 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_MakeTpCall( |
52 | PyThreadState *tstate, |
53 | PyObject *callable, |
54 | PyObject *const *args, Py_ssize_t nargs, |
55 | PyObject *keywords); |
56 | |
57 | #define PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)) ((size_t)1 << (8 * sizeof(size_t) - 1)) |
58 | |
59 | static inline Py_ssize_t |
60 | PyVectorcall_NARGS(size_t n) |
61 | { |
62 | return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)); |
63 | } |
64 | |
65 | static inline vectorcallfunc |
66 | PyVectorcall_Function(PyObject *callable) |
67 | { |
68 | PyTypeObject *tp; |
69 | Py_ssize_t offset; |
70 | vectorcallfunc ptr; |
71 | |
72 | assert(callable != NULL)((void) sizeof ((callable != ((void*)0)) ? 1 : 0), __extension__ ({ if (callable != ((void*)0)) ; else __assert_fail ("callable != NULL" , "/usr/include/python3.9/cpython/abstract.h", 72, __extension__ __PRETTY_FUNCTION__); })); |
73 | tp = Py_TYPE(callable)(((PyObject*)(callable))->ob_type); |
74 | if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL(1UL << 11))) { |
75 | return NULL((void*)0); |
76 | } |
77 | assert(PyCallable_Check(callable))((void) sizeof ((PyCallable_Check(callable)) ? 1 : 0), __extension__ ({ if (PyCallable_Check(callable)) ; else __assert_fail ("PyCallable_Check(callable)" , "/usr/include/python3.9/cpython/abstract.h", 77, __extension__ __PRETTY_FUNCTION__); })); |
78 | offset = tp->tp_vectorcall_offset; |
79 | assert(offset > 0)((void) sizeof ((offset > 0) ? 1 : 0), __extension__ ({ if (offset > 0) ; else __assert_fail ("offset > 0", "/usr/include/python3.9/cpython/abstract.h" , 79, __extension__ __PRETTY_FUNCTION__); })); |
80 | memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); |
The code calls sizeof() on a pointer type. This can produce an unexpected result | |
81 | return ptr; |
82 | } |
83 | |
84 | /* Call the callable object 'callable' with the "vectorcall" calling |
85 | convention. |
86 | |
87 | args is a C array for positional arguments. |
88 | |
89 | nargsf is the number of positional arguments plus optionally the flag |
90 | PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to |
91 | modify args[-1]. |
92 | |
93 | kwnames is a tuple of keyword names. The values of the keyword arguments |
94 | are stored in "args" after the positional arguments (note that the number |
95 | of keyword arguments does not change nargsf). kwnames can also be NULL if |
96 | there are no keyword arguments. |
97 | |
98 | keywords must only contain strings and all keys must be unique. |
99 | |
100 | Return the result on success. Raise an exception and return NULL on |
101 | error. */ |
102 | static inline PyObject * |
103 | _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, |
104 | PyObject *const *args, size_t nargsf, |
105 | PyObject *kwnames) |
106 | { |
107 | vectorcallfunc func; |
108 | PyObject *res; |
109 | |
110 | assert(kwnames == NULL || PyTuple_Check(kwnames))((void) sizeof ((kwnames == ((void*)0) || PyType_HasFeature(( ((PyObject*)(kwnames))->ob_type), (1UL << 26))) ? 1 : 0), __extension__ ({ if (kwnames == ((void*)0) || PyType_HasFeature ((((PyObject*)(kwnames))->ob_type), (1UL << 26))) ; else __assert_fail ("kwnames == NULL || PyTuple_Check(kwnames)", "/usr/include/python3.9/cpython/abstract.h" , 110, __extension__ __PRETTY_FUNCTION__); })); |
111 | assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0)((void) sizeof ((args != ((void*)0) || PyVectorcall_NARGS(nargsf ) == 0) ? 1 : 0), __extension__ ({ if (args != ((void*)0) || PyVectorcall_NARGS (nargsf) == 0) ; else __assert_fail ("args != NULL || PyVectorcall_NARGS(nargsf) == 0" , "/usr/include/python3.9/cpython/abstract.h", 111, __extension__ __PRETTY_FUNCTION__); })); |
112 | |
113 | func = PyVectorcall_Function(callable); |
114 | if (func == NULL((void*)0)) { |
115 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
116 | return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); |
117 | } |
118 | res = func(callable, args, nargsf, kwnames); |
119 | return _Py_CheckFunctionResult(tstate, callable, res, NULL((void*)0)); |
120 | } |
121 | |
122 | static inline PyObject * |
123 | PyObject_Vectorcall(PyObject *callable, PyObject *const *args, |
124 | size_t nargsf, PyObject *kwnames) |
125 | { |
126 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
127 | return _PyObject_VectorcallTstate(tstate, callable, |
128 | args, nargsf, kwnames); |
129 | } |
130 | |
131 | // Backwards compatibility aliases for API that was provisional in Python 3.8 |
132 | #define _PyObject_VectorcallPyObject_Vectorcall PyObject_Vectorcall |
133 | #define _PyObject_VectorcallMethodPyObject_VectorcallMethod PyObject_VectorcallMethod |
134 | #define _PyObject_FastCallDictPyObject_VectorcallDict PyObject_VectorcallDict |
135 | #define _PyVectorcall_FunctionPyVectorcall_Function PyVectorcall_Function |
136 | #define _PyObject_CallOneArgPyObject_CallOneArg PyObject_CallOneArg |
137 | #define _PyObject_CallMethodNoArgsPyObject_CallMethodNoArgs PyObject_CallMethodNoArgs |
138 | #define _PyObject_CallMethodOneArgPyObject_CallMethodOneArg PyObject_CallMethodOneArg |
139 | |
140 | /* Same as PyObject_Vectorcall except that keyword arguments are passed as |
141 | dict, which may be NULL if there are no keyword arguments. */ |
142 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyObject_VectorcallDict( |
143 | PyObject *callable, |
144 | PyObject *const *args, |
145 | size_t nargsf, |
146 | PyObject *kwargs); |
147 | |
148 | /* Call "callable" (which must support vectorcall) with positional arguments |
149 | "tuple" and keyword arguments "dict". "dict" may also be NULL */ |
150 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); |
151 | |
152 | static inline PyObject * |
153 | _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) |
154 | { |
155 | return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL((void*)0)); |
156 | } |
157 | |
158 | /* Same as PyObject_Vectorcall except without keyword arguments */ |
159 | static inline PyObject * |
160 | _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) |
161 | { |
162 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
163 | return _PyObject_FastCallTstate(tstate, func, args, nargs); |
164 | } |
165 | |
166 | /* Call a callable without any arguments |
167 | Private static inline function variant of public function |
168 | PyObject_CallNoArgs(). */ |
169 | static inline PyObject * |
170 | _PyObject_CallNoArg(PyObject *func) { |
171 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
172 | return _PyObject_VectorcallTstate(tstate, func, NULL((void*)0), 0, NULL((void*)0)); |
173 | } |
174 | |
175 | static inline PyObject * |
176 | PyObject_CallOneArg(PyObject *func, PyObject *arg) |
177 | { |
178 | PyObject *_args[2]; |
179 | PyObject **args; |
180 | PyThreadState *tstate; |
181 | size_t nargsf; |
182 | |
183 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 183, __extension__ __PRETTY_FUNCTION__); })); |
184 | args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET |
185 | args[0] = arg; |
186 | tstate = PyThreadState_GET()PyThreadState_Get(); |
187 | nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)); |
188 | return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL((void*)0)); |
189 | } |
190 | |
191 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyObject_VectorcallMethod( |
192 | PyObject *name, PyObject *const *args, |
193 | size_t nargsf, PyObject *kwnames); |
194 | |
195 | static inline PyObject * |
196 | PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) |
197 | { |
198 | return PyObject_VectorcallMethod(name, &self, |
199 | 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
200 | } |
201 | |
202 | static inline PyObject * |
203 | PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) |
204 | { |
205 | PyObject *args[2] = {self, arg}; |
206 | |
207 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 207, __extension__ __PRETTY_FUNCTION__); })); |
208 | return PyObject_VectorcallMethod(name, args, |
209 | 2 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
210 | } |
211 | |
212 | /* Like PyObject_CallMethod(), but expect a _Py_Identifier* |
213 | as the method name. */ |
214 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodId(PyObject *obj, |
215 | _Py_Identifier *name, |
216 | const char *format, ...); |
217 | |
218 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodId_SizeT(PyObject *obj, |
219 | _Py_Identifier *name, |
220 | const char *format, |
221 | ...); |
222 | |
223 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodIdObjArgs( |
224 | PyObject *obj, |
225 | struct _Py_Identifier *name, |
226 | ...); |
227 | |
228 | static inline PyObject * |
229 | _PyObject_VectorcallMethodId( |
230 | _Py_Identifier *name, PyObject *const *args, |
231 | size_t nargsf, PyObject *kwnames) |
232 | { |
233 | PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ |
234 | if (!oname) { |
235 | return NULL((void*)0); |
236 | } |
237 | return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); |
238 | } |
239 | |
240 | static inline PyObject * |
241 | _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) |
242 | { |
243 | return _PyObject_VectorcallMethodId(name, &self, |
244 | 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
245 | } |
246 | |
247 | static inline PyObject * |
248 | _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) |
249 | { |
250 | PyObject *args[2] = {self, arg}; |
251 | |
252 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 252, __extension__ __PRETTY_FUNCTION__); })); |
253 | return _PyObject_VectorcallMethodId(name, args, |
254 | 2 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
255 | } |
256 | |
257 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_HasLen(PyObject *o); |
258 | |
259 | /* Guess the size of object 'o' using len(o) or o.__length_hint__(). |
260 | If neither of those return a non-negative value, then return the default |
261 | value. If one of the calls fails, this function returns -1. */ |
262 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t); |
263 | |
264 | /* === New Buffer API ============================================ */ |
265 | |
266 | /* Return 1 if the getbuffer function is available, otherwise return 0. */ |
267 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_CheckBuffer(PyObject *obj); |
268 | |
269 | /* This is a C-API version of the getbuffer function call. It checks |
270 | to make sure object has the required function pointer and issues the |
271 | call. |
272 | |
273 | Returns -1 and raises an error on failure and returns 0 on success. */ |
274 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, |
275 | int flags); |
276 | |
277 | /* Get the memory area pointed to by the indices for the buffer given. |
278 | Note that view->ndim is the assumed size of indices. */ |
279 | PyAPI_FUNC(void *)__attribute__ ((visibility ("default"))) void * PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); |
280 | |
281 | /* Return the implied itemsize of the data-format area from a |
282 | struct-style description. */ |
283 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t PyBuffer_SizeFromFormat(const char *format); |
284 | |
285 | /* Implementation in memoryobject.c */ |
286 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_ToContiguous(void *buf, Py_buffer *view, |
287 | Py_ssize_t len, char order); |
288 | |
289 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_FromContiguous(Py_buffer *view, void *buf, |
290 | Py_ssize_t len, char order); |
291 | |
292 | /* Copy len bytes of data from the contiguous chunk of memory |
293 | pointed to by buf into the buffer exported by obj. Return |
294 | 0 on success and return -1 and raise a PyBuffer_Error on |
295 | error (i.e. the object does not have a buffer interface or |
296 | it is not working). |
297 | |
298 | If fort is 'F', then if the object is multi-dimensional, |
299 | then the data will be copied into the array in |
300 | Fortran-style (first dimension varies the fastest). If |
301 | fort is 'C', then the data will be copied into the array |
302 | in C-style (last dimension varies the fastest). If fort |
303 | is 'A', then it does not matter and the copy will be made |
304 | in whatever way is more efficient. */ |
305 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_CopyData(PyObject *dest, PyObject *src); |
306 | |
307 | /* Copy the data from the src buffer to the buffer of destination. */ |
308 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_IsContiguous(const Py_buffer *view, char fort); |
309 | |
310 | /*Fill the strides array with byte-strides of a contiguous |
311 | (Fortran-style if fort is 'F' or C-style otherwise) |
312 | array of the given shape with the given number of bytes |
313 | per element. */ |
314 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void PyBuffer_FillContiguousStrides(int ndims, |
315 | Py_ssize_t *shape, |
316 | Py_ssize_t *strides, |
317 | int itemsize, |
318 | char fort); |
319 | |
320 | /* Fills in a buffer-info structure correctly for an exporter |
321 | that can only share a contiguous chunk of memory of |
322 | "unsigned bytes" of the given length. |
323 | |
324 | Returns 0 on success and -1 (with raising an error) on error. */ |
325 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, |
326 | Py_ssize_t len, int readonly, |
327 | int flags); |
328 | |
329 | /* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ |
330 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void PyBuffer_Release(Py_buffer *view); |
331 | |
332 | /* ==== Iterators ================================================ */ |
333 | |
334 | #define PyIter_Check(obj)((((PyObject*)(obj))->ob_type)->tp_iternext != ((void*) 0) && (((PyObject*)(obj))->ob_type)->tp_iternext != &_PyObject_NextNotImplemented) \ |
335 | (Py_TYPE(obj)(((PyObject*)(obj))->ob_type)->tp_iternext != NULL((void*)0) && \ |
336 | Py_TYPE(obj)(((PyObject*)(obj))->ob_type)->tp_iternext != &_PyObject_NextNotImplemented) |
337 | |
338 | /* === Sequence protocol ================================================ */ |
339 | |
340 | /* Assume tp_as_sequence and sq_item exist and that 'i' does not |
341 | need to be corrected for a negative index. */ |
342 | #define PySequence_ITEM(o, i)( (((PyObject*)(o))->ob_type)->tp_as_sequence->sq_item (o, i) )\ |
343 | ( Py_TYPE(o)(((PyObject*)(o))->ob_type)->tp_as_sequence->sq_item(o, i) ) |
344 | |
345 | #define PY_ITERSEARCH_COUNT1 1 |
346 | #define PY_ITERSEARCH_INDEX2 2 |
347 | #define PY_ITERSEARCH_CONTAINS3 3 |
348 | |
349 | /* Iterate over seq. |
350 | |
351 | Result depends on the operation: |
352 | |
353 | PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if |
354 | error. |
355 | PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of |
356 | obj in seq; set ValueError and return -1 if none found; |
357 | also return -1 on error. |
358 | PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on |
359 | error. */ |
360 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t _PySequence_IterSearch(PyObject *seq, |
361 | PyObject *obj, int operation); |
362 | |
363 | /* === Mapping protocol ================================================= */ |
364 | |
365 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); |
366 | |
367 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); |
368 | |
369 | PyAPI_FUNC(char *const *)__attribute__ ((visibility ("default"))) char *const * _PySequence_BytesToCharpArray(PyObject* self); |
370 | |
371 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_FreeCharPArray(char *const array[]); |
372 | |
373 | /* For internal use by buffer API functions */ |
374 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_add_one_to_index_F(int nd, Py_ssize_t *index, |
375 | const Py_ssize_t *shape); |
376 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_add_one_to_index_C(int nd, Py_ssize_t *index, |
377 | const Py_ssize_t *shape); |
378 | |
379 | /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ |
380 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _Py_convert_optional_to_ssize_t(PyObject *, void *); |
381 | |
382 | #ifdef __cplusplus |
383 | } |
384 | #endif |
File: | abstract.h |
Warning: | line 80, column 46 The code calls sizeof() on a pointer type. This can produce an unexpected result |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | #ifndef Py_CPYTHON_ABSTRACTOBJECT_H |
2 | # error "this header file must not be included directly" |
3 | #endif |
4 | |
5 | #ifdef __cplusplus |
6 | extern "C" { |
7 | #endif |
8 | |
9 | /* === Object Protocol ================================================== */ |
10 | |
11 | #ifdef PY_SSIZE_T_CLEAN |
12 | # define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT |
13 | #endif |
14 | |
15 | /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) |
16 | format to a Python dictionary ("kwargs" dict). |
17 | |
18 | The type of kwnames keys is not checked. The final function getting |
19 | arguments is responsible to check if all keys are strings, for example using |
20 | PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). |
21 | |
22 | Duplicate keys are merged using the last value. If duplicate keys must raise |
23 | an exception, the caller is responsible to implement an explicit keys on |
24 | kwnames. */ |
25 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyStack_AsDict( |
26 | PyObject *const *values, |
27 | PyObject *kwnames); |
28 | |
29 | /* Suggested size (number of positional arguments) for arrays of PyObject* |
30 | allocated on a C stack to avoid allocating memory on the heap memory. Such |
31 | array is used to pass positional arguments to call functions of the |
32 | PyObject_Vectorcall() family. |
33 | |
34 | The size is chosen to not abuse the C stack and so limit the risk of stack |
35 | overflow. The size is also chosen to allow using the small stack for most |
36 | function calls of the Python standard library. On 64-bit CPU, it allocates |
37 | 40 bytes on the stack. */ |
38 | #define _PY_FASTCALL_SMALL_STACK5 5 |
39 | |
40 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _Py_CheckFunctionResult( |
41 | PyThreadState *tstate, |
42 | PyObject *callable, |
43 | PyObject *result, |
44 | const char *where); |
45 | |
46 | /* === Vectorcall protocol (PEP 590) ============================= */ |
47 | |
48 | /* Call callable using tp_call. Arguments are like PyObject_Vectorcall() |
49 | or PyObject_FastCallDict() (both forms are supported), |
50 | except that nargs is plainly the number of arguments without flags. */ |
51 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_MakeTpCall( |
52 | PyThreadState *tstate, |
53 | PyObject *callable, |
54 | PyObject *const *args, Py_ssize_t nargs, |
55 | PyObject *keywords); |
56 | |
57 | #define PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)) ((size_t)1 << (8 * sizeof(size_t) - 1)) |
58 | |
59 | static inline Py_ssize_t |
60 | PyVectorcall_NARGS(size_t n) |
61 | { |
62 | return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)); |
63 | } |
64 | |
65 | static inline vectorcallfunc |
66 | PyVectorcall_Function(PyObject *callable) |
67 | { |
68 | PyTypeObject *tp; |
69 | Py_ssize_t offset; |
70 | vectorcallfunc ptr; |
71 | |
72 | assert(callable != NULL)((void) sizeof ((callable != ((void*)0)) ? 1 : 0), __extension__ ({ if (callable != ((void*)0)) ; else __assert_fail ("callable != NULL" , "/usr/include/python3.9/cpython/abstract.h", 72, __extension__ __PRETTY_FUNCTION__); })); |
73 | tp = Py_TYPE(callable)(((PyObject*)(callable))->ob_type); |
74 | if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL(1UL << 11))) { |
75 | return NULL((void*)0); |
76 | } |
77 | assert(PyCallable_Check(callable))((void) sizeof ((PyCallable_Check(callable)) ? 1 : 0), __extension__ ({ if (PyCallable_Check(callable)) ; else __assert_fail ("PyCallable_Check(callable)" , "/usr/include/python3.9/cpython/abstract.h", 77, __extension__ __PRETTY_FUNCTION__); })); |
78 | offset = tp->tp_vectorcall_offset; |
79 | assert(offset > 0)((void) sizeof ((offset > 0) ? 1 : 0), __extension__ ({ if (offset > 0) ; else __assert_fail ("offset > 0", "/usr/include/python3.9/cpython/abstract.h" , 79, __extension__ __PRETTY_FUNCTION__); })); |
80 | memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); |
The code calls sizeof() on a pointer type. This can produce an unexpected result | |
81 | return ptr; |
82 | } |
83 | |
84 | /* Call the callable object 'callable' with the "vectorcall" calling |
85 | convention. |
86 | |
87 | args is a C array for positional arguments. |
88 | |
89 | nargsf is the number of positional arguments plus optionally the flag |
90 | PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to |
91 | modify args[-1]. |
92 | |
93 | kwnames is a tuple of keyword names. The values of the keyword arguments |
94 | are stored in "args" after the positional arguments (note that the number |
95 | of keyword arguments does not change nargsf). kwnames can also be NULL if |
96 | there are no keyword arguments. |
97 | |
98 | keywords must only contain strings and all keys must be unique. |
99 | |
100 | Return the result on success. Raise an exception and return NULL on |
101 | error. */ |
102 | static inline PyObject * |
103 | _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, |
104 | PyObject *const *args, size_t nargsf, |
105 | PyObject *kwnames) |
106 | { |
107 | vectorcallfunc func; |
108 | PyObject *res; |
109 | |
110 | assert(kwnames == NULL || PyTuple_Check(kwnames))((void) sizeof ((kwnames == ((void*)0) || PyType_HasFeature(( ((PyObject*)(kwnames))->ob_type), (1UL << 26))) ? 1 : 0), __extension__ ({ if (kwnames == ((void*)0) || PyType_HasFeature ((((PyObject*)(kwnames))->ob_type), (1UL << 26))) ; else __assert_fail ("kwnames == NULL || PyTuple_Check(kwnames)", "/usr/include/python3.9/cpython/abstract.h" , 110, __extension__ __PRETTY_FUNCTION__); })); |
111 | assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0)((void) sizeof ((args != ((void*)0) || PyVectorcall_NARGS(nargsf ) == 0) ? 1 : 0), __extension__ ({ if (args != ((void*)0) || PyVectorcall_NARGS (nargsf) == 0) ; else __assert_fail ("args != NULL || PyVectorcall_NARGS(nargsf) == 0" , "/usr/include/python3.9/cpython/abstract.h", 111, __extension__ __PRETTY_FUNCTION__); })); |
112 | |
113 | func = PyVectorcall_Function(callable); |
114 | if (func == NULL((void*)0)) { |
115 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
116 | return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); |
117 | } |
118 | res = func(callable, args, nargsf, kwnames); |
119 | return _Py_CheckFunctionResult(tstate, callable, res, NULL((void*)0)); |
120 | } |
121 | |
122 | static inline PyObject * |
123 | PyObject_Vectorcall(PyObject *callable, PyObject *const *args, |
124 | size_t nargsf, PyObject *kwnames) |
125 | { |
126 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
127 | return _PyObject_VectorcallTstate(tstate, callable, |
128 | args, nargsf, kwnames); |
129 | } |
130 | |
131 | // Backwards compatibility aliases for API that was provisional in Python 3.8 |
132 | #define _PyObject_VectorcallPyObject_Vectorcall PyObject_Vectorcall |
133 | #define _PyObject_VectorcallMethodPyObject_VectorcallMethod PyObject_VectorcallMethod |
134 | #define _PyObject_FastCallDictPyObject_VectorcallDict PyObject_VectorcallDict |
135 | #define _PyVectorcall_FunctionPyVectorcall_Function PyVectorcall_Function |
136 | #define _PyObject_CallOneArgPyObject_CallOneArg PyObject_CallOneArg |
137 | #define _PyObject_CallMethodNoArgsPyObject_CallMethodNoArgs PyObject_CallMethodNoArgs |
138 | #define _PyObject_CallMethodOneArgPyObject_CallMethodOneArg PyObject_CallMethodOneArg |
139 | |
140 | /* Same as PyObject_Vectorcall except that keyword arguments are passed as |
141 | dict, which may be NULL if there are no keyword arguments. */ |
142 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyObject_VectorcallDict( |
143 | PyObject *callable, |
144 | PyObject *const *args, |
145 | size_t nargsf, |
146 | PyObject *kwargs); |
147 | |
148 | /* Call "callable" (which must support vectorcall) with positional arguments |
149 | "tuple" and keyword arguments "dict". "dict" may also be NULL */ |
150 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); |
151 | |
152 | static inline PyObject * |
153 | _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) |
154 | { |
155 | return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL((void*)0)); |
156 | } |
157 | |
158 | /* Same as PyObject_Vectorcall except without keyword arguments */ |
159 | static inline PyObject * |
160 | _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) |
161 | { |
162 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
163 | return _PyObject_FastCallTstate(tstate, func, args, nargs); |
164 | } |
165 | |
166 | /* Call a callable without any arguments |
167 | Private static inline function variant of public function |
168 | PyObject_CallNoArgs(). */ |
169 | static inline PyObject * |
170 | _PyObject_CallNoArg(PyObject *func) { |
171 | PyThreadState *tstate = PyThreadState_GET()PyThreadState_Get(); |
172 | return _PyObject_VectorcallTstate(tstate, func, NULL((void*)0), 0, NULL((void*)0)); |
173 | } |
174 | |
175 | static inline PyObject * |
176 | PyObject_CallOneArg(PyObject *func, PyObject *arg) |
177 | { |
178 | PyObject *_args[2]; |
179 | PyObject **args; |
180 | PyThreadState *tstate; |
181 | size_t nargsf; |
182 | |
183 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 183, __extension__ __PRETTY_FUNCTION__); })); |
184 | args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET |
185 | args[0] = arg; |
186 | tstate = PyThreadState_GET()PyThreadState_Get(); |
187 | nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)); |
188 | return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL((void*)0)); |
189 | } |
190 | |
191 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * PyObject_VectorcallMethod( |
192 | PyObject *name, PyObject *const *args, |
193 | size_t nargsf, PyObject *kwnames); |
194 | |
195 | static inline PyObject * |
196 | PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) |
197 | { |
198 | return PyObject_VectorcallMethod(name, &self, |
199 | 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
200 | } |
201 | |
202 | static inline PyObject * |
203 | PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) |
204 | { |
205 | PyObject *args[2] = {self, arg}; |
206 | |
207 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 207, __extension__ __PRETTY_FUNCTION__); })); |
208 | return PyObject_VectorcallMethod(name, args, |
209 | 2 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
210 | } |
211 | |
212 | /* Like PyObject_CallMethod(), but expect a _Py_Identifier* |
213 | as the method name. */ |
214 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodId(PyObject *obj, |
215 | _Py_Identifier *name, |
216 | const char *format, ...); |
217 | |
218 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodId_SizeT(PyObject *obj, |
219 | _Py_Identifier *name, |
220 | const char *format, |
221 | ...); |
222 | |
223 | PyAPI_FUNC(PyObject *)__attribute__ ((visibility ("default"))) PyObject * _PyObject_CallMethodIdObjArgs( |
224 | PyObject *obj, |
225 | struct _Py_Identifier *name, |
226 | ...); |
227 | |
228 | static inline PyObject * |
229 | _PyObject_VectorcallMethodId( |
230 | _Py_Identifier *name, PyObject *const *args, |
231 | size_t nargsf, PyObject *kwnames) |
232 | { |
233 | PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ |
234 | if (!oname) { |
235 | return NULL((void*)0); |
236 | } |
237 | return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); |
238 | } |
239 | |
240 | static inline PyObject * |
241 | _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) |
242 | { |
243 | return _PyObject_VectorcallMethodId(name, &self, |
244 | 1 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
245 | } |
246 | |
247 | static inline PyObject * |
248 | _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) |
249 | { |
250 | PyObject *args[2] = {self, arg}; |
251 | |
252 | assert(arg != NULL)((void) sizeof ((arg != ((void*)0)) ? 1 : 0), __extension__ ( { if (arg != ((void*)0)) ; else __assert_fail ("arg != NULL", "/usr/include/python3.9/cpython/abstract.h", 252, __extension__ __PRETTY_FUNCTION__); })); |
253 | return _PyObject_VectorcallMethodId(name, args, |
254 | 2 | PY_VECTORCALL_ARGUMENTS_OFFSET((size_t)1 << (8 * sizeof(size_t) - 1)), NULL((void*)0)); |
255 | } |
256 | |
257 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_HasLen(PyObject *o); |
258 | |
259 | /* Guess the size of object 'o' using len(o) or o.__length_hint__(). |
260 | If neither of those return a non-negative value, then return the default |
261 | value. If one of the calls fails, this function returns -1. */ |
262 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t); |
263 | |
264 | /* === New Buffer API ============================================ */ |
265 | |
266 | /* Return 1 if the getbuffer function is available, otherwise return 0. */ |
267 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_CheckBuffer(PyObject *obj); |
268 | |
269 | /* This is a C-API version of the getbuffer function call. It checks |
270 | to make sure object has the required function pointer and issues the |
271 | call. |
272 | |
273 | Returns -1 and raises an error on failure and returns 0 on success. */ |
274 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, |
275 | int flags); |
276 | |
277 | /* Get the memory area pointed to by the indices for the buffer given. |
278 | Note that view->ndim is the assumed size of indices. */ |
279 | PyAPI_FUNC(void *)__attribute__ ((visibility ("default"))) void * PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); |
280 | |
281 | /* Return the implied itemsize of the data-format area from a |
282 | struct-style description. */ |
283 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t PyBuffer_SizeFromFormat(const char *format); |
284 | |
285 | /* Implementation in memoryobject.c */ |
286 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_ToContiguous(void *buf, Py_buffer *view, |
287 | Py_ssize_t len, char order); |
288 | |
289 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_FromContiguous(Py_buffer *view, void *buf, |
290 | Py_ssize_t len, char order); |
291 | |
292 | /* Copy len bytes of data from the contiguous chunk of memory |
293 | pointed to by buf into the buffer exported by obj. Return |
294 | 0 on success and return -1 and raise a PyBuffer_Error on |
295 | error (i.e. the object does not have a buffer interface or |
296 | it is not working). |
297 | |
298 | If fort is 'F', then if the object is multi-dimensional, |
299 | then the data will be copied into the array in |
300 | Fortran-style (first dimension varies the fastest). If |
301 | fort is 'C', then the data will be copied into the array |
302 | in C-style (last dimension varies the fastest). If fort |
303 | is 'A', then it does not matter and the copy will be made |
304 | in whatever way is more efficient. */ |
305 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyObject_CopyData(PyObject *dest, PyObject *src); |
306 | |
307 | /* Copy the data from the src buffer to the buffer of destination. */ |
308 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_IsContiguous(const Py_buffer *view, char fort); |
309 | |
310 | /*Fill the strides array with byte-strides of a contiguous |
311 | (Fortran-style if fort is 'F' or C-style otherwise) |
312 | array of the given shape with the given number of bytes |
313 | per element. */ |
314 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void PyBuffer_FillContiguousStrides(int ndims, |
315 | Py_ssize_t *shape, |
316 | Py_ssize_t *strides, |
317 | int itemsize, |
318 | char fort); |
319 | |
320 | /* Fills in a buffer-info structure correctly for an exporter |
321 | that can only share a contiguous chunk of memory of |
322 | "unsigned bytes" of the given length. |
323 | |
324 | Returns 0 on success and -1 (with raising an error) on error. */ |
325 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, |
326 | Py_ssize_t len, int readonly, |
327 | int flags); |
328 | |
329 | /* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ |
330 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void PyBuffer_Release(Py_buffer *view); |
331 | |
332 | /* ==== Iterators ================================================ */ |
333 | |
334 | #define PyIter_Check(obj)((((PyObject*)(obj))->ob_type)->tp_iternext != ((void*) 0) && (((PyObject*)(obj))->ob_type)->tp_iternext != &_PyObject_NextNotImplemented) \ |
335 | (Py_TYPE(obj)(((PyObject*)(obj))->ob_type)->tp_iternext != NULL((void*)0) && \ |
336 | Py_TYPE(obj)(((PyObject*)(obj))->ob_type)->tp_iternext != &_PyObject_NextNotImplemented) |
337 | |
338 | /* === Sequence protocol ================================================ */ |
339 | |
340 | /* Assume tp_as_sequence and sq_item exist and that 'i' does not |
341 | need to be corrected for a negative index. */ |
342 | #define PySequence_ITEM(o, i)( (((PyObject*)(o))->ob_type)->tp_as_sequence->sq_item (o, i) )\ |
343 | ( Py_TYPE(o)(((PyObject*)(o))->ob_type)->tp_as_sequence->sq_item(o, i) ) |
344 | |
345 | #define PY_ITERSEARCH_COUNT1 1 |
346 | #define PY_ITERSEARCH_INDEX2 2 |
347 | #define PY_ITERSEARCH_CONTAINS3 3 |
348 | |
349 | /* Iterate over seq. |
350 | |
351 | Result depends on the operation: |
352 | |
353 | PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if |
354 | error. |
355 | PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of |
356 | obj in seq; set ValueError and return -1 if none found; |
357 | also return -1 on error. |
358 | PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on |
359 | error. */ |
360 | PyAPI_FUNC(Py_ssize_t)__attribute__ ((visibility ("default"))) Py_ssize_t _PySequence_IterSearch(PyObject *seq, |
361 | PyObject *obj, int operation); |
362 | |
363 | /* === Mapping protocol ================================================= */ |
364 | |
365 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); |
366 | |
367 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); |
368 | |
369 | PyAPI_FUNC(char *const *)__attribute__ ((visibility ("default"))) char *const * _PySequence_BytesToCharpArray(PyObject* self); |
370 | |
371 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_FreeCharPArray(char *const array[]); |
372 | |
373 | /* For internal use by buffer API functions */ |
374 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_add_one_to_index_F(int nd, Py_ssize_t *index, |
375 | const Py_ssize_t *shape); |
376 | PyAPI_FUNC(void)__attribute__ ((visibility ("default"))) void _Py_add_one_to_index_C(int nd, Py_ssize_t *index, |
377 | const Py_ssize_t *shape); |
378 | |
379 | /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ |
380 | PyAPI_FUNC(int)__attribute__ ((visibility ("default"))) int _Py_convert_optional_to_ssize_t(PyObject *, void *); |
381 | |
382 | #ifdef __cplusplus |
383 | } |
384 | #endif |