1#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
2#  error "this header file must not be included directly"
3#endif
4
5/* === Object Protocol ================================================== */
6
7#ifdef PY_SSIZE_T_CLEAN
8#  define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
9#endif
10
11/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
12   format to a Python dictionary ("kwargs" dict).
13
14   The type of kwnames keys is not checked. The final function getting
15   arguments is responsible to check if all keys are strings, for example using
16   PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
17
18   Duplicate keys are merged using the last value. If duplicate keys must raise
19   an exception, the caller is responsible to implement an explicit keys on
20   kwnames. */
21PyAPI_FUNC(PyObject *) _PyStack_AsDict(
22    PyObject *const *values,
23    PyObject *kwnames);
24
25/* Suggested size (number of positional arguments) for arrays of PyObject*
26   allocated on a C stack to avoid allocating memory on the heap memory. Such
27   array is used to pass positional arguments to call functions of the
28   PyObject_Vectorcall() family.
29
30   The size is chosen to not abuse the C stack and so limit the risk of stack
31   overflow. The size is also chosen to allow using the small stack for most
32   function calls of the Python standard library. On 64-bit CPU, it allocates
33   40 bytes on the stack. */
34#define _PY_FASTCALL_SMALL_STACK 5
35
36PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
37    PyThreadState *tstate,
38    PyObject *callable,
39    PyObject *result,
40    const char *where);
41
42/* === Vectorcall protocol (PEP 590) ============================= */
43
44/* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
45   or PyObject_FastCallDict() (both forms are supported),
46   except that nargs is plainly the number of arguments without flags. */
47PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
48    PyThreadState *tstate,
49    PyObject *callable,
50    PyObject *const *args, Py_ssize_t nargs,
51    PyObject *keywords);
52
53#define PY_VECTORCALL_ARGUMENTS_OFFSET \
54    (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1))
55
56static inline Py_ssize_t
57PyVectorcall_NARGS(size_t n)
58{
59    return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
60}
61
62PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
63
64PyAPI_FUNC(PyObject *) PyObject_Vectorcall(
65    PyObject *callable,
66    PyObject *const *args,
67    size_t nargsf,
68    PyObject *kwnames);
69
70// Backwards compatibility aliases for API that was provisional in Python 3.8
71#define _PyObject_Vectorcall PyObject_Vectorcall
72#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
73#define _PyObject_FastCallDict PyObject_VectorcallDict
74#define _PyVectorcall_Function PyVectorcall_Function
75#define _PyObject_CallOneArg PyObject_CallOneArg
76#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
77#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
78
79/* Same as PyObject_Vectorcall except that keyword arguments are passed as
80   dict, which may be NULL if there are no keyword arguments. */
81PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
82    PyObject *callable,
83    PyObject *const *args,
84    size_t nargsf,
85    PyObject *kwargs);
86
87/* Call "callable" (which must support vectorcall) with positional arguments
88   "tuple" and keyword arguments "dict". "dict" may also be NULL */
89PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
90
91// Same as PyObject_Vectorcall(), except without keyword arguments
92PyAPI_FUNC(PyObject *) _PyObject_FastCall(
93    PyObject *func,
94    PyObject *const *args,
95    Py_ssize_t nargs);
96
97PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg);
98
99PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
100    PyObject *name, PyObject *const *args,
101    size_t nargsf, PyObject *kwnames);
102
103static inline PyObject *
104PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
105{
106    size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
107    return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
108}
109
110static inline PyObject *
111PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
112{
113    PyObject *args[2] = {self, arg};
114    size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
115    assert(arg != NULL);
116    return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
117}
118
119PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
120                                            PyObject *name,
121                                            const char *format, ...);
122
123/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
124   as the method name. */
125PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
126                                              _Py_Identifier *name,
127                                              const char *format, ...);
128
129PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
130                                                    _Py_Identifier *name,
131                                                    const char *format,
132                                                    ...);
133
134PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
135    PyObject *obj,
136    _Py_Identifier *name,
137    ...);
138
139static inline PyObject *
140_PyObject_VectorcallMethodId(
141    _Py_Identifier *name, PyObject *const *args,
142    size_t nargsf, PyObject *kwnames)
143{
144    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
145    if (!oname) {
146        return _Py_NULL;
147    }
148    return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
149}
150
151static inline PyObject *
152_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
153{
154    size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
155    return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
156}
157
158static inline PyObject *
159_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
160{
161    PyObject *args[2] = {self, arg};
162    size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
163    assert(arg != NULL);
164    return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
165}
166
167PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
168
169/* Guess the size of object 'o' using len(o) or o.__length_hint__().
170   If neither of those return a non-negative value, then return the default
171   value.  If one of the calls fails, this function returns -1. */
172PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
173
174/* === Sequence protocol ================================================ */
175
176/* Assume tp_as_sequence and sq_item exist and that 'i' does not
177   need to be corrected for a negative index. */
178#define PySequence_ITEM(o, i)\
179    ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
180
181#define PY_ITERSEARCH_COUNT    1
182#define PY_ITERSEARCH_INDEX    2
183#define PY_ITERSEARCH_CONTAINS 3
184
185/* Iterate over seq.
186
187   Result depends on the operation:
188
189   PY_ITERSEARCH_COUNT:  return # of times obj appears in seq; -1 if
190     error.
191   PY_ITERSEARCH_INDEX:  return 0-based index of first occurrence of
192     obj in seq; set ValueError and return -1 if none found;
193     also return -1 on error.
194   PY_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on
195     error. */
196PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
197                                              PyObject *obj, int operation);
198
199/* === Mapping protocol ================================================= */
200
201PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
202
203PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
204
205PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
206
207PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
208
209/* For internal use by buffer API functions */
210PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
211                                        const Py_ssize_t *shape);
212PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
213                                        const Py_ssize_t *shape);
214
215/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
216PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
217
218/* Same as PyNumber_Index but can return an instance of a subclass of int. */
219PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
220