| 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. */ |
| 21 | PyAPI_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 | |
| 36 | PyAPI_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. */ |
| 47 | PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( |
| 48 | PyThreadState *tstate, |
| 49 | PyObject *callable, |
| 50 | PyObject *const *args, Py_ssize_t nargs, |
| 51 | PyObject *keywords); |
| 52 | |
| 53 | // PyVectorcall_NARGS() is exported as a function for the stable ABI. |
| 54 | // Here (when we are not using the stable ABI), the name is overridden to |
| 55 | // call a static inline function for best performance. |
| 56 | #define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) |
| 57 | static inline Py_ssize_t |
| 58 | _PyVectorcall_NARGS(size_t n) |
| 59 | { |
| 60 | return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; |
| 61 | } |
| 62 | |
| 63 | PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); |
| 64 | |
| 65 | // Backwards compatibility aliases for API that was provisional in Python 3.8 |
| 66 | #define _PyObject_Vectorcall PyObject_Vectorcall |
| 67 | #define _PyObject_VectorcallMethod PyObject_VectorcallMethod |
| 68 | #define _PyObject_FastCallDict PyObject_VectorcallDict |
| 69 | #define _PyVectorcall_Function PyVectorcall_Function |
| 70 | #define _PyObject_CallOneArg PyObject_CallOneArg |
| 71 | #define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs |
| 72 | #define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg |
| 73 | |
| 74 | /* Same as PyObject_Vectorcall except that keyword arguments are passed as |
| 75 | dict, which may be NULL if there are no keyword arguments. */ |
| 76 | PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( |
| 77 | PyObject *callable, |
| 78 | PyObject *const *args, |
| 79 | size_t nargsf, |
| 80 | PyObject *kwargs); |
| 81 | |
| 82 | // Same as PyObject_Vectorcall(), except without keyword arguments |
| 83 | PyAPI_FUNC(PyObject *) _PyObject_FastCall( |
| 84 | PyObject *func, |
| 85 | PyObject *const *args, |
| 86 | Py_ssize_t nargs); |
| 87 | |
| 88 | PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg); |
| 89 | |
| 90 | static inline PyObject * |
| 91 | PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) |
| 92 | { |
| 93 | size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
| 94 | return PyObject_VectorcallMethod(name, args: &self, nargsf, _Py_NULL); |
| 95 | } |
| 96 | |
| 97 | static inline PyObject * |
| 98 | PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) |
| 99 | { |
| 100 | PyObject *args[2] = {self, arg}; |
| 101 | size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
| 102 | assert(arg != NULL); |
| 103 | return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL); |
| 104 | } |
| 105 | |
| 106 | PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj, |
| 107 | PyObject *name, |
| 108 | const char *format, ...); |
| 109 | |
| 110 | /* Like PyObject_CallMethod(), but expect a _Py_Identifier* |
| 111 | as the method name. */ |
| 112 | PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, |
| 113 | _Py_Identifier *name, |
| 114 | const char *format, ...); |
| 115 | |
| 116 | PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, |
| 117 | _Py_Identifier *name, |
| 118 | const char *format, |
| 119 | ...); |
| 120 | |
| 121 | PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( |
| 122 | PyObject *obj, |
| 123 | _Py_Identifier *name, |
| 124 | ...); |
| 125 | |
| 126 | static inline PyObject * |
| 127 | _PyObject_VectorcallMethodId( |
| 128 | _Py_Identifier *name, PyObject *const *args, |
| 129 | size_t nargsf, PyObject *kwnames) |
| 130 | { |
| 131 | PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ |
| 132 | if (!oname) { |
| 133 | return _Py_NULL; |
| 134 | } |
| 135 | return PyObject_VectorcallMethod(name: oname, args, nargsf, kwnames); |
| 136 | } |
| 137 | |
| 138 | static inline PyObject * |
| 139 | _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) |
| 140 | { |
| 141 | size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
| 142 | return _PyObject_VectorcallMethodId(name, args: &self, nargsf, _Py_NULL); |
| 143 | } |
| 144 | |
| 145 | static inline PyObject * |
| 146 | _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) |
| 147 | { |
| 148 | PyObject *args[2] = {self, arg}; |
| 149 | size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
| 150 | assert(arg != NULL); |
| 151 | return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL); |
| 152 | } |
| 153 | |
| 154 | PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); |
| 155 | |
| 156 | /* Guess the size of object 'o' using len(o) or o.__length_hint__(). |
| 157 | If neither of those return a non-negative value, then return the default |
| 158 | value. If one of the calls fails, this function returns -1. */ |
| 159 | PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); |
| 160 | |
| 161 | /* === Sequence protocol ================================================ */ |
| 162 | |
| 163 | /* Assume tp_as_sequence and sq_item exist and that 'i' does not |
| 164 | need to be corrected for a negative index. */ |
| 165 | #define PySequence_ITEM(o, i)\ |
| 166 | ( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) ) |
| 167 | |
| 168 | #define PY_ITERSEARCH_COUNT 1 |
| 169 | #define PY_ITERSEARCH_INDEX 2 |
| 170 | #define PY_ITERSEARCH_CONTAINS 3 |
| 171 | |
| 172 | /* Iterate over seq. |
| 173 | |
| 174 | Result depends on the operation: |
| 175 | |
| 176 | PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if |
| 177 | error. |
| 178 | PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of |
| 179 | obj in seq; set ValueError and return -1 if none found; |
| 180 | also return -1 on error. |
| 181 | PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on |
| 182 | error. */ |
| 183 | PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, |
| 184 | PyObject *obj, int operation); |
| 185 | |
| 186 | /* === Mapping protocol ================================================= */ |
| 187 | |
| 188 | PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); |
| 189 | |
| 190 | PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); |
| 191 | |
| 192 | PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); |
| 193 | |
| 194 | PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); |
| 195 | |
| 196 | /* For internal use by buffer API functions */ |
| 197 | PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, |
| 198 | const Py_ssize_t *shape); |
| 199 | PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, |
| 200 | const Py_ssize_t *shape); |
| 201 | |
| 202 | /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ |
| 203 | PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); |
| 204 | |
| 205 | /* Same as PyNumber_Index but can return an instance of a subclass of int. */ |
| 206 | PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); |
| 207 | |