diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/tools/python3/src/Include/cpython/abstract.h | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Include/cpython/abstract.h')
-rw-r--r-- | contrib/tools/python3/src/Include/cpython/abstract.h | 768 |
1 files changed, 384 insertions, 384 deletions
diff --git a/contrib/tools/python3/src/Include/cpython/abstract.h b/contrib/tools/python3/src/Include/cpython/abstract.h index 9a3737c42f..0f1304d26a 100644 --- a/contrib/tools/python3/src/Include/cpython/abstract.h +++ b/contrib/tools/python3/src/Include/cpython/abstract.h @@ -1,384 +1,384 @@ -#ifndef Py_CPYTHON_ABSTRACTOBJECT_H -# error "this header file must not be included directly" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* === Object Protocol ================================================== */ - -#ifdef PY_SSIZE_T_CLEAN -# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT -#endif - -/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) - format to a Python dictionary ("kwargs" dict). - - The type of kwnames keys is not checked. The final function getting - arguments is responsible to check if all keys are strings, for example using - PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). - - Duplicate keys are merged using the last value. If duplicate keys must raise - an exception, the caller is responsible to implement an explicit keys on - kwnames. */ -PyAPI_FUNC(PyObject *) _PyStack_AsDict( - PyObject *const *values, - PyObject *kwnames); - -/* Suggested size (number of positional arguments) for arrays of PyObject* - allocated on a C stack to avoid allocating memory on the heap memory. Such - array is used to pass positional arguments to call functions of the - PyObject_Vectorcall() family. - - The size is chosen to not abuse the C stack and so limit the risk of stack - overflow. The size is also chosen to allow using the small stack for most - function calls of the Python standard library. On 64-bit CPU, it allocates - 40 bytes on the stack. */ -#define _PY_FASTCALL_SMALL_STACK 5 - -PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( - PyThreadState *tstate, - PyObject *callable, - PyObject *result, - const char *where); - -/* === Vectorcall protocol (PEP 590) ============================= */ - -/* Call callable using tp_call. Arguments are like PyObject_Vectorcall() - or PyObject_FastCallDict() (both forms are supported), - except that nargs is plainly the number of arguments without flags. */ -PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( - PyThreadState *tstate, - PyObject *callable, - PyObject *const *args, Py_ssize_t nargs, - PyObject *keywords); - -#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) - -static inline Py_ssize_t -PyVectorcall_NARGS(size_t n) -{ - return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; -} - -static inline vectorcallfunc -PyVectorcall_Function(PyObject *callable) -{ - PyTypeObject *tp; - Py_ssize_t offset; - vectorcallfunc ptr; - - assert(callable != NULL); - tp = Py_TYPE(callable); - if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { - return NULL; - } - assert(PyCallable_Check(callable)); - offset = tp->tp_vectorcall_offset; - assert(offset > 0); - memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); - return ptr; -} - -/* Call the callable object 'callable' with the "vectorcall" calling - convention. - - args is a C array for positional arguments. - - nargsf is the number of positional arguments plus optionally the flag - PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to - modify args[-1]. - - kwnames is a tuple of keyword names. The values of the keyword arguments - are stored in "args" after the positional arguments (note that the number - of keyword arguments does not change nargsf). kwnames can also be NULL if - there are no keyword arguments. - - keywords must only contain strings and all keys must be unique. - - Return the result on success. Raise an exception and return NULL on - error. */ -static inline PyObject * -_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) -{ - vectorcallfunc func; - PyObject *res; - - assert(kwnames == NULL || PyTuple_Check(kwnames)); - assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); - - func = PyVectorcall_Function(callable); - if (func == NULL) { - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); - } - res = func(callable, args, nargsf, kwnames); - return _Py_CheckFunctionResult(tstate, callable, res, NULL); -} - -static inline PyObject * -PyObject_Vectorcall(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = PyThreadState_GET(); - return _PyObject_VectorcallTstate(tstate, callable, - args, nargsf, kwnames); -} - -// Backwards compatibility aliases for API that was provisional in Python 3.8 -#define _PyObject_Vectorcall PyObject_Vectorcall -#define _PyObject_VectorcallMethod PyObject_VectorcallMethod -#define _PyObject_FastCallDict PyObject_VectorcallDict -#define _PyVectorcall_Function PyVectorcall_Function -#define _PyObject_CallOneArg PyObject_CallOneArg -#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs -#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg - -/* Same as PyObject_Vectorcall except that keyword arguments are passed as - dict, which may be NULL if there are no keyword arguments. */ -PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwargs); - -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - -static inline PyObject * -_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) -{ - return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); -} - -/* Same as PyObject_Vectorcall except without keyword arguments */ -static inline PyObject * -_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) -{ - PyThreadState *tstate = PyThreadState_GET(); - return _PyObject_FastCallTstate(tstate, func, args, nargs); -} - -/* Call a callable without any arguments - Private static inline function variant of public function - PyObject_CallNoArgs(). */ -static inline PyObject * -_PyObject_CallNoArg(PyObject *func) { - PyThreadState *tstate = PyThreadState_GET(); - return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); -} - -static inline PyObject * -PyObject_CallOneArg(PyObject *func, PyObject *arg) -{ - PyObject *_args[2]; - PyObject **args; - PyThreadState *tstate; - size_t nargsf; - - assert(arg != NULL); - args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET - args[0] = arg; - tstate = PyThreadState_GET(); - nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; - return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); -} - -PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( - PyObject *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - -static inline PyObject * -PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) -{ - return PyObject_VectorcallMethod(name, &self, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); -} - -static inline PyObject * -PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) -{ - PyObject *args[2] = {self, arg}; - - assert(arg != NULL); - return PyObject_VectorcallMethod(name, args, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); -} - -/* Like PyObject_CallMethod(), but expect a _Py_Identifier* - as the method name. */ -PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, - _Py_Identifier *name, - const char *format, ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, - _Py_Identifier *name, - const char *format, - ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( - PyObject *obj, - struct _Py_Identifier *name, - ...); - -static inline PyObject * -_PyObject_VectorcallMethodId( - _Py_Identifier *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames) -{ - PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ - if (!oname) { - return NULL; - } - return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); -} - -static inline PyObject * -_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) -{ - return _PyObject_VectorcallMethodId(name, &self, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); -} - -static inline PyObject * -_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) -{ - PyObject *args[2] = {self, arg}; - - assert(arg != NULL); - return _PyObject_VectorcallMethodId(name, args, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); -} - -PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); - -/* Guess the size of object 'o' using len(o) or o.__length_hint__(). - If neither of those return a non-negative value, then return the default - value. If one of the calls fails, this function returns -1. */ -PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); - -/* === New Buffer API ============================================ */ - -/* Return 1 if the getbuffer function is available, otherwise return 0. */ -PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); - -/* This is a C-API version of the getbuffer function call. It checks - to make sure object has the required function pointer and issues the - call. - - Returns -1 and raises an error on failure and returns 0 on success. */ -PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, - int flags); - -/* Get the memory area pointed to by the indices for the buffer given. - Note that view->ndim is the assumed size of indices. */ -PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); - -/* Return the implied itemsize of the data-format area from a - struct-style description. */ -PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format); - -/* Implementation in memoryobject.c */ -PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, - Py_ssize_t len, char order); - -PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, - Py_ssize_t len, char order); - -/* Copy len bytes of data from the contiguous chunk of memory - pointed to by buf into the buffer exported by obj. Return - 0 on success and return -1 and raise a PyBuffer_Error on - error (i.e. the object does not have a buffer interface or - it is not working). - - If fort is 'F', then if the object is multi-dimensional, - then the data will be copied into the array in - Fortran-style (first dimension varies the fastest). If - fort is 'C', then the data will be copied into the array - in C-style (last dimension varies the fastest). If fort - is 'A', then it does not matter and the copy will be made - in whatever way is more efficient. */ -PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); - -/* Copy the data from the src buffer to the buffer of destination. */ -PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); - -/*Fill the strides array with byte-strides of a contiguous - (Fortran-style if fort is 'F' or C-style otherwise) - array of the given shape with the given number of bytes - per element. */ -PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, - Py_ssize_t *shape, - Py_ssize_t *strides, - int itemsize, - char fort); - -/* Fills in a buffer-info structure correctly for an exporter - that can only share a contiguous chunk of memory of - "unsigned bytes" of the given length. - - Returns 0 on success and -1 (with raising an error) on error. */ -PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, - Py_ssize_t len, int readonly, - int flags); - -/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ -PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); - -/* ==== Iterators ================================================ */ - -#define PyIter_Check(obj) \ - (Py_TYPE(obj)->tp_iternext != NULL && \ - Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented) - -/* === Sequence protocol ================================================ */ - -/* Assume tp_as_sequence and sq_item exist and that 'i' does not - need to be corrected for a negative index. */ -#define PySequence_ITEM(o, i)\ - ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) - -#define PY_ITERSEARCH_COUNT 1 -#define PY_ITERSEARCH_INDEX 2 -#define PY_ITERSEARCH_CONTAINS 3 - -/* Iterate over seq. - - Result depends on the operation: - - PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if - error. - PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of - obj in seq; set ValueError and return -1 if none found; - also return -1 on error. - PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on - error. */ -PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, - PyObject *obj, int operation); - -/* === Mapping protocol ================================================= */ - -PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); - -PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); - -PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); - -PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); - -/* For internal use by buffer API functions */ -PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, - const Py_ssize_t *shape); -PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, - const Py_ssize_t *shape); - -/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ -PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); - -#ifdef __cplusplus -} -#endif +#ifndef Py_CPYTHON_ABSTRACTOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* === Object Protocol ================================================== */ + +#ifdef PY_SSIZE_T_CLEAN +# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT +#endif + +/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) + format to a Python dictionary ("kwargs" dict). + + The type of kwnames keys is not checked. The final function getting + arguments is responsible to check if all keys are strings, for example using + PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). + + Duplicate keys are merged using the last value. If duplicate keys must raise + an exception, the caller is responsible to implement an explicit keys on + kwnames. */ +PyAPI_FUNC(PyObject *) _PyStack_AsDict( + PyObject *const *values, + PyObject *kwnames); + +/* Suggested size (number of positional arguments) for arrays of PyObject* + allocated on a C stack to avoid allocating memory on the heap memory. Such + array is used to pass positional arguments to call functions of the + PyObject_Vectorcall() family. + + The size is chosen to not abuse the C stack and so limit the risk of stack + overflow. The size is also chosen to allow using the small stack for most + function calls of the Python standard library. On 64-bit CPU, it allocates + 40 bytes on the stack. */ +#define _PY_FASTCALL_SMALL_STACK 5 + +PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( + PyThreadState *tstate, + PyObject *callable, + PyObject *result, + const char *where); + +/* === Vectorcall protocol (PEP 590) ============================= */ + +/* Call callable using tp_call. Arguments are like PyObject_Vectorcall() + or PyObject_FastCallDict() (both forms are supported), + except that nargs is plainly the number of arguments without flags. */ +PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( + PyThreadState *tstate, + PyObject *callable, + PyObject *const *args, Py_ssize_t nargs, + PyObject *keywords); + +#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + +static inline Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; +} + +static inline vectorcallfunc +PyVectorcall_Function(PyObject *callable) +{ + PyTypeObject *tp; + Py_ssize_t offset; + vectorcallfunc ptr; + + assert(callable != NULL); + tp = Py_TYPE(callable); + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + offset = tp->tp_vectorcall_offset; + assert(offset > 0); + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + +/* Call the callable object 'callable' with the "vectorcall" calling + convention. + + args is a C array for positional arguments. + + nargsf is the number of positional arguments plus optionally the flag + PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to + modify args[-1]. + + kwnames is a tuple of keyword names. The values of the keyword arguments + are stored in "args" after the positional arguments (note that the number + of keyword arguments does not change nargsf). kwnames can also be NULL if + there are no keyword arguments. + + keywords must only contain strings and all keys must be unique. + + Return the result on success. Raise an exception and return NULL on + error. */ +static inline PyObject * +_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) +{ + vectorcallfunc func; + PyObject *res; + + assert(kwnames == NULL || PyTuple_Check(kwnames)); + assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); + + func = PyVectorcall_Function(callable); + if (func == NULL) { + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); + } + res = func(callable, args, nargsf, kwnames); + return _Py_CheckFunctionResult(tstate, callable, res, NULL); +} + +static inline PyObject * +PyObject_Vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, callable, + args, nargsf, kwnames); +} + +// Backwards compatibility aliases for API that was provisional in Python 3.8 +#define _PyObject_Vectorcall PyObject_Vectorcall +#define _PyObject_VectorcallMethod PyObject_VectorcallMethod +#define _PyObject_FastCallDict PyObject_VectorcallDict +#define _PyVectorcall_Function PyVectorcall_Function +#define _PyObject_CallOneArg PyObject_CallOneArg +#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs +#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg + +/* Same as PyObject_Vectorcall except that keyword arguments are passed as + dict, which may be NULL if there are no keyword arguments. */ +PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwargs); + +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + +static inline PyObject * +_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) +{ + return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); +} + +/* Same as PyObject_Vectorcall except without keyword arguments */ +static inline PyObject * +_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) +{ + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_FastCallTstate(tstate, func, args, nargs); +} + +/* Call a callable without any arguments + Private static inline function variant of public function + PyObject_CallNoArgs(). */ +static inline PyObject * +_PyObject_CallNoArg(PyObject *func) { + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); +} + +static inline PyObject * +PyObject_CallOneArg(PyObject *func, PyObject *arg) +{ + PyObject *_args[2]; + PyObject **args; + PyThreadState *tstate; + size_t nargsf; + + assert(arg != NULL); + args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET + args[0] = arg; + tstate = PyThreadState_GET(); + nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); +} + +PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( + PyObject *name, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + +static inline PyObject * +PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) +{ + return PyObject_VectorcallMethod(name, &self, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + +static inline PyObject * +PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) +{ + PyObject *args[2] = {self, arg}; + + assert(arg != NULL); + return PyObject_VectorcallMethod(name, args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + +/* Like PyObject_CallMethod(), but expect a _Py_Identifier* + as the method name. */ +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, + _Py_Identifier *name, + const char *format, ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, + _Py_Identifier *name, + const char *format, + ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( + PyObject *obj, + struct _Py_Identifier *name, + ...); + +static inline PyObject * +_PyObject_VectorcallMethodId( + _Py_Identifier *name, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) { + return NULL; + } + return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); +} + +static inline PyObject * +_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) +{ + return _PyObject_VectorcallMethodId(name, &self, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + +static inline PyObject * +_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) +{ + PyObject *args[2] = {self, arg}; + + assert(arg != NULL); + return _PyObject_VectorcallMethodId(name, args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + +PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); + +/* Guess the size of object 'o' using len(o) or o.__length_hint__(). + If neither of those return a non-negative value, then return the default + value. If one of the calls fails, this function returns -1. */ +PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); + +/* === New Buffer API ============================================ */ + +/* Return 1 if the getbuffer function is available, otherwise return 0. */ +PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); + +/* This is a C-API version of the getbuffer function call. It checks + to make sure object has the required function pointer and issues the + call. + + Returns -1 and raises an error on failure and returns 0 on success. */ +PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, + int flags); + +/* Get the memory area pointed to by the indices for the buffer given. + Note that view->ndim is the assumed size of indices. */ +PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); + +/* Return the implied itemsize of the data-format area from a + struct-style description. */ +PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format); + +/* Implementation in memoryobject.c */ +PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, + Py_ssize_t len, char order); + +PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, + Py_ssize_t len, char order); + +/* Copy len bytes of data from the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. Return + 0 on success and return -1 and raise a PyBuffer_Error on + error (i.e. the object does not have a buffer interface or + it is not working). + + If fort is 'F', then if the object is multi-dimensional, + then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort + is 'A', then it does not matter and the copy will be made + in whatever way is more efficient. */ +PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); + +/* Copy the data from the src buffer to the buffer of destination. */ +PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); + +/*Fill the strides array with byte-strides of a contiguous + (Fortran-style if fort is 'F' or C-style otherwise) + array of the given shape with the given number of bytes + per element. */ +PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, + Py_ssize_t *shape, + Py_ssize_t *strides, + int itemsize, + char fort); + +/* Fills in a buffer-info structure correctly for an exporter + that can only share a contiguous chunk of memory of + "unsigned bytes" of the given length. + + Returns 0 on success and -1 (with raising an error) on error. */ +PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, + Py_ssize_t len, int readonly, + int flags); + +/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ +PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); + +/* ==== Iterators ================================================ */ + +#define PyIter_Check(obj) \ + (Py_TYPE(obj)->tp_iternext != NULL && \ + Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented) + +/* === Sequence protocol ================================================ */ + +/* Assume tp_as_sequence and sq_item exist and that 'i' does not + need to be corrected for a negative index. */ +#define PySequence_ITEM(o, i)\ + ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + +#define PY_ITERSEARCH_COUNT 1 +#define PY_ITERSEARCH_INDEX 2 +#define PY_ITERSEARCH_CONTAINS 3 + +/* Iterate over seq. + + Result depends on the operation: + + PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if + error. + PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of + obj in seq; set ValueError and return -1 if none found; + also return -1 on error. + PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on + error. */ +PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, + PyObject *obj, int operation); + +/* === Mapping protocol ================================================= */ + +PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); + +PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); + +PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); + +PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); + +/* For internal use by buffer API functions */ +PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); +PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); + +/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ +PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); + +#ifdef __cplusplus +} +#endif |