diff options
author | AlexSm <alex@ydb.tech> | 2024-03-05 10:40:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-05 12:40:59 +0300 |
commit | 1ac13c847b5358faba44dbb638a828e24369467b (patch) | |
tree | 07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Include/cpython | |
parent | ffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff) | |
download | ydb-1ac13c847b5358faba44dbb638a828e24369467b.tar.gz |
Library import 16 (#2433)
Co-authored-by: robot-piglet <robot-piglet@yandex-team.com>
Co-authored-by: deshevoy <deshevoy@yandex-team.com>
Co-authored-by: robot-contrib <robot-contrib@yandex-team.com>
Co-authored-by: thegeorg <thegeorg@yandex-team.com>
Co-authored-by: robot-ya-builder <robot-ya-builder@yandex-team.com>
Co-authored-by: svidyuk <svidyuk@yandex-team.com>
Co-authored-by: shadchin <shadchin@yandex-team.com>
Co-authored-by: robot-ratatosk <robot-ratatosk@yandex-team.com>
Co-authored-by: innokentii <innokentii@yandex-team.com>
Co-authored-by: arkady-e1ppa <arkady-e1ppa@yandex-team.com>
Co-authored-by: snermolaev <snermolaev@yandex-team.com>
Co-authored-by: dimdim11 <dimdim11@yandex-team.com>
Co-authored-by: kickbutt <kickbutt@yandex-team.com>
Co-authored-by: abdullinsaid <abdullinsaid@yandex-team.com>
Co-authored-by: korsunandrei <korsunandrei@yandex-team.com>
Co-authored-by: petrk <petrk@yandex-team.com>
Co-authored-by: miroslav2 <miroslav2@yandex-team.com>
Co-authored-by: serjflint <serjflint@yandex-team.com>
Co-authored-by: akhropov <akhropov@yandex-team.com>
Co-authored-by: prettyboy <prettyboy@yandex-team.com>
Co-authored-by: ilikepugs <ilikepugs@yandex-team.com>
Co-authored-by: hiddenpath <hiddenpath@yandex-team.com>
Co-authored-by: mikhnenko <mikhnenko@yandex-team.com>
Co-authored-by: spreis <spreis@yandex-team.com>
Co-authored-by: andreyshspb <andreyshspb@yandex-team.com>
Co-authored-by: dimaandreev <dimaandreev@yandex-team.com>
Co-authored-by: rashid <rashid@yandex-team.com>
Co-authored-by: robot-ydb-importer <robot-ydb-importer@yandex-team.com>
Co-authored-by: r-vetrov <r-vetrov@yandex-team.com>
Co-authored-by: ypodlesov <ypodlesov@yandex-team.com>
Co-authored-by: zaverden <zaverden@yandex-team.com>
Co-authored-by: vpozdyayev <vpozdyayev@yandex-team.com>
Co-authored-by: robot-cozmo <robot-cozmo@yandex-team.com>
Co-authored-by: v-korovin <v-korovin@yandex-team.com>
Co-authored-by: arikon <arikon@yandex-team.com>
Co-authored-by: khoden <khoden@yandex-team.com>
Co-authored-by: psydmm <psydmm@yandex-team.com>
Co-authored-by: robot-javacom <robot-javacom@yandex-team.com>
Co-authored-by: dtorilov <dtorilov@yandex-team.com>
Co-authored-by: sennikovmv <sennikovmv@yandex-team.com>
Co-authored-by: hcpp <hcpp@ydb.tech>
Diffstat (limited to 'contrib/tools/python3/Include/cpython')
50 files changed, 5926 insertions, 0 deletions
diff --git a/contrib/tools/python3/Include/cpython/abstract.h b/contrib/tools/python3/Include/cpython/abstract.h new file mode 100644 index 0000000000..3b27aab2fc --- /dev/null +++ b/contrib/tools/python3/Include/cpython/abstract.h @@ -0,0 +1,206 @@ +#ifndef Py_CPYTHON_ABSTRACTOBJECT_H +# error "this header file must not be included directly" +#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); + +// PyVectorcall_NARGS() is exported as a function for the stable ABI. +// Here (when we are not using the stable ABI), the name is overridden to +// call a static inline function for best performance. +#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) +static inline Py_ssize_t +_PyVectorcall_NARGS(size_t n) +{ + return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; +} + +PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); + +// 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); + +// Same as PyObject_Vectorcall(), except without keyword arguments +PyAPI_FUNC(PyObject *) _PyObject_FastCall( + PyObject *func, + PyObject *const *args, + Py_ssize_t nargs); + +PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg); + +static inline PyObject * +PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) +{ + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL); +} + +static inline PyObject * +PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) +{ + PyObject *args[2] = {self, arg}; + size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; + assert(arg != NULL); + return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL); +} + +PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj, + PyObject *name, + const char *format, ...); + +/* 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, + _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 _Py_NULL; + } + return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); +} + +static inline PyObject * +_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) +{ + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL); +} + +static inline PyObject * +_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) +{ + PyObject *args[2] = {self, arg}; + size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; + assert(arg != NULL); + return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_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); + +/* === 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 *); + +/* Same as PyNumber_Index but can return an instance of a subclass of int. */ +PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); diff --git a/contrib/tools/python3/Include/cpython/bytearrayobject.h b/contrib/tools/python3/Include/cpython/bytearrayobject.h new file mode 100644 index 0000000000..9ba176eb2d --- /dev/null +++ b/contrib/tools/python3/Include/cpython/bytearrayobject.h @@ -0,0 +1,34 @@ +#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H +# error "this header file must not be included directly" +#endif + +/* Object layout */ +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ + char *ob_bytes; /* Physical backing buffer */ + char *ob_start; /* Logical start inside ob_bytes */ + Py_ssize_t ob_exports; /* How many buffer exports */ +} PyByteArrayObject; + +PyAPI_DATA(char) _PyByteArray_empty_string[]; + +/* Macros and static inline functions, trading safety for speed */ +#define _PyByteArray_CAST(op) \ + (assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op)) + +static inline char* PyByteArray_AS_STRING(PyObject *op) +{ + PyByteArrayObject *self = _PyByteArray_CAST(op); + if (Py_SIZE(self)) { + return self->ob_start; + } + return _PyByteArray_empty_string; +} +#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self)) + +static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { + PyByteArrayObject *self = _PyByteArray_CAST(op); + return Py_SIZE(self); +} +#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) diff --git a/contrib/tools/python3/Include/cpython/bytesobject.h b/contrib/tools/python3/Include/cpython/bytesobject.h new file mode 100644 index 0000000000..e982031c10 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/bytesobject.h @@ -0,0 +1,129 @@ +#ifndef Py_CPYTHON_BYTESOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + PyObject_VAR_HEAD + Py_DEPRECATED(3.11) Py_hash_t ob_shash; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the byte string or -1 if not computed yet. + */ +} PyBytesObject; + +PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( + const char *format, + Py_ssize_t format_len, + PyObject *args, + int use_bytearray); +PyAPI_FUNC(PyObject*) _PyBytes_FromHex( + PyObject *string, + int use_bytearray); + +/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ +PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, const char **); + +/* Macros and static inline functions, trading safety for speed */ +#define _PyBytes_CAST(op) \ + (assert(PyBytes_Check(op)), _Py_CAST(PyBytesObject*, op)) + +static inline char* PyBytes_AS_STRING(PyObject *op) +{ + return _PyBytes_CAST(op)->ob_sval; +} +#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op)) + +static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { + PyBytesObject *self = _PyBytes_CAST(op); + return Py_SIZE(self); +} +#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) + +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, + x must be an iterable object. */ +PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); + + +/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". + A _PyBytesWriter variable must be declared at the end of variables in a + function to optimize the memory allocation on the stack. */ +typedef struct { + /* bytes, bytearray or NULL (when the small buffer is used) */ + PyObject *buffer; + + /* Number of allocated size. */ + Py_ssize_t allocated; + + /* Minimum number of allocated bytes, + incremented by _PyBytesWriter_Prepare() */ + Py_ssize_t min_size; + + /* If non-zero, use a bytearray instead of a bytes object for buffer. */ + int use_bytearray; + + /* If non-zero, overallocate the buffer (default: 0). + This flag must be zero if use_bytearray is non-zero. */ + int overallocate; + + /* Stack buffer */ + int use_small_buffer; + char small_buffer[512]; +} _PyBytesWriter; + +/* Initialize a bytes writer + + By default, the overallocation is disabled. Set the overallocate attribute + to control the allocation of the buffer. */ +PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); + +/* Get the buffer content and reset the writer. + Return a bytes object, or a bytearray object if use_bytearray is non-zero. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, + void *str); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); + +/* Allocate the buffer to write size bytes. + Return the pointer to the beginning of buffer data. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, + Py_ssize_t size); + +/* Ensure that the buffer is large enough to write *size* bytes. + Add size to the writer minimum size (min_size attribute). + + str is the current pointer inside the buffer. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Resize the buffer to make it larger. + The new buffer may be larger than size bytes because of overallocation. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. + + Note: size must be greater than the number of allocated bytes in the writer. + + This function doesn't use the writer minimum size (min_size attribute). + + See also _PyBytesWriter_Prepare(). + */ +PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Write bytes. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, + void *str, + const void *bytes, + Py_ssize_t size); diff --git a/contrib/tools/python3/Include/cpython/cellobject.h b/contrib/tools/python3/Include/cpython/cellobject.h new file mode 100644 index 0000000000..47a6a49149 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/cellobject.h @@ -0,0 +1,44 @@ +/* Cell object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_CELLOBJECT_H +#define Py_CELLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + /* Content of the cell or NULL when empty */ + PyObject *ob_ref; +} PyCellObject; + +PyAPI_DATA(PyTypeObject) PyCell_Type; + +#define PyCell_Check(op) Py_IS_TYPE((op), &PyCell_Type) + +PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); +PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); +PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); + +static inline PyObject* PyCell_GET(PyObject *op) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + return cell->ob_ref; +} +#define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op)) + +static inline void PyCell_SET(PyObject *op, PyObject *value) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + cell->ob_ref = value; +} +#define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/ceval.h b/contrib/tools/python3/Include/cpython/ceval.h new file mode 100644 index 0000000000..a9616bd6a4 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/ceval.h @@ -0,0 +1,35 @@ +#ifndef Py_CPYTHON_CEVAL_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *); +PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *); +PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); + +/* Helper to look up a builtin object */ +PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); + +PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc); + +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); + +PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *); + +PyAPI_FUNC(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc); +// Old name -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t +_PyEval_RequestCodeExtraIndex(freefunc f) { + return PyUnstable_Eval_RequestCodeExtraIndex(f); +} + +PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); diff --git a/contrib/tools/python3/Include/cpython/classobject.h b/contrib/tools/python3/Include/cpython/classobject.h new file mode 100644 index 0000000000..d7c9ddd133 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/classobject.h @@ -0,0 +1,71 @@ +/* Former class object interface -- now only bound methods are here */ + +/* Revealing some structures (not for general use) */ + +#ifndef Py_LIMITED_API +#ifndef Py_CLASSOBJECT_H +#define Py_CLASSOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *im_func; /* The callable object implementing the method */ + PyObject *im_self; /* The instance it is bound to */ + PyObject *im_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; +} PyMethodObject; + +PyAPI_DATA(PyTypeObject) PyMethod_Type; + +#define PyMethod_Check(op) Py_IS_TYPE((op), &PyMethod_Type) + +PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); + +#define _PyMethod_CAST(meth) \ + (assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth)) + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) { + return _PyMethod_CAST(meth)->im_func; +} +#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth)) + +static inline PyObject* PyMethod_GET_SELF(PyObject *meth) { + return _PyMethod_CAST(meth)->im_self; +} +#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth)) + +typedef struct { + PyObject_HEAD + PyObject *func; +} PyInstanceMethodObject; + +PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; + +#define PyInstanceMethod_Check(op) Py_IS_TYPE((op), &PyInstanceMethod_Type) + +PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); + +#define _PyInstanceMethod_CAST(meth) \ + (assert(PyInstanceMethod_Check(meth)), \ + _Py_CAST(PyInstanceMethodObject*, meth)) + +/* Static inline function for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) { + return _PyInstanceMethod_CAST(meth)->func; +} +#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth)) + +#ifdef __cplusplus +} +#endif +#endif // !Py_CLASSOBJECT_H +#endif // !Py_LIMITED_API diff --git a/contrib/tools/python3/Include/cpython/code.h b/contrib/tools/python3/Include/cpython/code.h new file mode 100644 index 0000000000..03834b20c3 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/code.h @@ -0,0 +1,389 @@ +/* Definitions for bytecode */ + +#ifndef Py_LIMITED_API +#ifndef Py_CODE_H +#define Py_CODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Count of all local monitoring events */ +#define _PY_MONITORING_LOCAL_EVENTS 10 +/* Count of all "real" monitoring events (not derived from other events) */ +#define _PY_MONITORING_UNGROUPED_EVENTS 15 +/* Count of all monitoring events */ +#define _PY_MONITORING_EVENTS 17 + +/* Tables of which tools are active for each monitored event. */ +/* For 3.12 ABI compatibility this is over sized */ +typedef struct _Py_LocalMonitors { + /* Only _PY_MONITORING_LOCAL_EVENTS of these are used */ + uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS]; +} _Py_LocalMonitors; + +typedef struct _Py_GlobalMonitors { + uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS]; +} _Py_GlobalMonitors; + +/* Each instruction in a code object is a fixed-width value, + * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG + * opcode allows for larger values but the current limit is 3 uses + * of EXTENDED_ARG (see Python/compile.c), for a maximum + * 32-bit value. This aligns with the note in Python/compile.c + * (compiler_addop_i_line) indicating that the max oparg value is + * 2**32 - 1, rather than INT_MAX. + */ + +typedef union { + uint16_t cache; + struct { + uint8_t code; + uint8_t arg; + } op; +} _Py_CODEUNIT; + + +/* These macros only remain defined for compatibility. */ +#define _Py_OPCODE(word) ((word).op.code) +#define _Py_OPARG(word) ((word).op.arg) + +static inline _Py_CODEUNIT +_py_make_codeunit(uint8_t opcode, uint8_t oparg) +{ + // No designated initialisers because of C++ compat + _Py_CODEUNIT word; + word.op.code = opcode; + word.op.arg = oparg; + return word; +} + +static inline void +_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) +{ + word->op.code = opcode; +} + +#define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg)) +#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), (opcode)) + + +typedef struct { + PyObject *_co_code; + PyObject *_co_varnames; + PyObject *_co_cellvars; + PyObject *_co_freevars; +} _PyCoCached; + +/* Ancilliary data structure used for instrumentation. + Line instrumentation creates an array of + these. One entry per code unit.*/ +typedef struct { + uint8_t original_opcode; + int8_t line_delta; +} _PyCoLineInstrumentationData; + +/* Main data structure used for instrumentation. + * This is allocated when needed for instrumentation + */ +typedef struct { + /* Monitoring specific to this code object */ + _Py_LocalMonitors local_monitors; + /* Monitoring that is active on this code object */ + _Py_LocalMonitors active_monitors; + /* The tools that are to be notified for events for the matching code unit */ + uint8_t *tools; + /* Information to support line events */ + _PyCoLineInstrumentationData *lines; + /* The tools that are to be notified for line events for the matching code unit */ + uint8_t *line_tools; + /* Information to support instruction events */ + /* The underlying instructions, which can themselves be instrumented */ + uint8_t *per_instruction_opcodes; + /* The tools that are to be notified for instruction events for the matching code unit */ + uint8_t *per_instruction_tools; +} _PyCoMonitoringData; + +// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are +// defined in this macro: +#define _PyCode_DEF(SIZE) { \ + PyObject_VAR_HEAD \ + \ + /* Note only the following fields are used in hash and/or comparisons \ + * \ + * - co_name \ + * - co_argcount \ + * - co_posonlyargcount \ + * - co_kwonlyargcount \ + * - co_nlocals \ + * - co_stacksize \ + * - co_flags \ + * - co_firstlineno \ + * - co_consts \ + * - co_names \ + * - co_localsplusnames \ + * This is done to preserve the name and line number for tracebacks \ + * and debuggers; otherwise, constant de-duplication would collapse \ + * identical functions/lambdas defined on different lines. \ + */ \ + \ + /* These fields are set with provided values on new code objects. */ \ + \ + /* The hottest fields (in the eval loop) are grouped here at the top. */ \ + PyObject *co_consts; /* list (constants used) */ \ + PyObject *co_names; /* list of strings (names used) */ \ + PyObject *co_exceptiontable; /* Byte string encoding exception handling \ + table */ \ + int co_flags; /* CO_..., see below */ \ + \ + /* The rest are not so impactful on performance. */ \ + int co_argcount; /* #arguments, except *args */ \ + int co_posonlyargcount; /* #positional only arguments */ \ + int co_kwonlyargcount; /* #keyword only arguments */ \ + int co_stacksize; /* #entries needed for evaluation stack */ \ + int co_firstlineno; /* first source line number */ \ + \ + /* redundant values (derived from co_localsplusnames and \ + co_localspluskinds) */ \ + int co_nlocalsplus; /* number of local + cell + free variables */ \ + int co_framesize; /* Size of frame in words */ \ + int co_nlocals; /* number of local variables */ \ + int co_ncellvars; /* total number of cell variables */ \ + int co_nfreevars; /* number of free variables */ \ + uint32_t co_version; /* version number */ \ + \ + PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \ + PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \ + per variable) */ \ + PyObject *co_filename; /* unicode (where it was loaded from) */ \ + PyObject *co_name; /* unicode (name, for reference) */ \ + PyObject *co_qualname; /* unicode (qualname, for reference) */ \ + PyObject *co_linetable; /* bytes object that holds location info */ \ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ + _PyCoCached *_co_cached; /* cached co_* attributes */ \ + uint64_t _co_instrumentation_version; /* current instrumentation version */ \ + _PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \ + int _co_firsttraceable; /* index of first traceable instruction */ \ + /* Scratch space for extra data relating to the code object. \ + Type is a void* to keep the format private in codeobject.c to force \ + people to go through the proper APIs. */ \ + void *co_extra; \ + char co_code_adaptive[(SIZE)]; \ +} + +/* Bytecode object */ +struct PyCodeObject _PyCode_DEF(1); + +/* Masks for co_flags above */ +#define CO_OPTIMIZED 0x0001 +#define CO_NEWLOCALS 0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 +#define CO_NESTED 0x0010 +#define CO_GENERATOR 0x0020 + +/* The CO_COROUTINE flag is set for coroutine functions (defined with + ``async def`` keywords) */ +#define CO_COROUTINE 0x0080 +#define CO_ITERABLE_COROUTINE 0x0100 +#define CO_ASYNC_GENERATOR 0x0200 + +/* bpo-39562: These constant values are changed in Python 3.9 + to prevent collision with compiler flags. CO_FUTURE_ and PyCF_ + constants must be kept unique. PyCF_ constants can use bits from + 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */ +#define CO_FUTURE_DIVISION 0x20000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x80000 +#define CO_FUTURE_PRINT_FUNCTION 0x100000 +#define CO_FUTURE_UNICODE_LITERALS 0x200000 + +#define CO_FUTURE_BARRY_AS_BDFL 0x400000 +#define CO_FUTURE_GENERATOR_STOP 0x800000 +#define CO_FUTURE_ANNOTATIONS 0x1000000 + +/* This should be defined if a future statement modifies the syntax. + For example, when a keyword is added. +*/ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD + +#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ + +PyAPI_DATA(PyTypeObject) PyCode_Type; + +#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type) + +static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nfreevars; +} + +static inline int PyCode_GetFirstFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nlocalsplus - op->co_nfreevars; +} + +#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive) +#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) + +/* Unstable public interface */ +PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New( + int, int, int, int, int, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, int, PyObject *, + PyObject *); + +PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs( + int, int, int, int, int, int, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, int, PyObject *, + PyObject *); + /* same as struct above */ +// Old names -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject * +PyCode_New( + int a, int b, int c, int d, int e, PyObject *f, PyObject *g, + PyObject *h, PyObject *i, PyObject *j, PyObject *k, + PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p, + PyObject *q) +{ + return PyUnstable_Code_New( + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); +} +_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject * +PyCode_NewWithPosOnlyArgs( + int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g, + PyObject *h, PyObject *i, PyObject *j, PyObject *k, + PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p, + PyObject *q) +{ + return PyUnstable_Code_NewWithPosOnlyArgs( + a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); +} + +/* Creates a new empty code object with the specified source location. */ +PyAPI_FUNC(PyCodeObject *) +PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); + +/* Return the line number associated with the specified bytecode index + in this code object. If you just need the line number of a frame, + use PyFrame_GetLineNumber() instead. */ +PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); + +PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *); + +#define PY_FOREACH_CODE_EVENT(V) \ + V(CREATE) \ + V(DESTROY) + +typedef enum { + #define PY_DEF_EVENT(op) PY_CODE_EVENT_##op, + PY_FOREACH_CODE_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyCodeEvent; + + +/* + * A callback that is invoked for different events in a code object's lifecycle. + * + * The callback is invoked with a borrowed reference to co, after it is + * created and before it is destroyed. + * + * If the callback sets an exception, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyCode_WatchCallback)( + PyCodeEvent event, + PyCodeObject* co); + +/* + * Register a per-interpreter callback that will be invoked for code object + * lifecycle events. + * + * Returns a handle that may be passed to PyCode_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the provided id. + */ +PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id); + +/* for internal use only */ +struct _opaque { + int computed_line; + const uint8_t *lo_next; + const uint8_t *limit; +}; + +typedef struct _line_offsets { + int ar_start; + int ar_end; + int ar_line; + struct _opaque opaque; +} PyCodeAddressRange; + +/* Update *bounds to describe the first and one-past-the-last instructions in the + same line as lasti. Return the number of that line. +*/ +PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds); + +/* Create a comparable key used to compare constants taking in account the + * object type. It is used to make sure types are not coerced (e.g., float and + * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms + * + * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items) + * depending on the type and the value. The type is the first item to not + * compare bytes and str which can raise a BytesWarning exception. */ +PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); + +PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, + PyObject *names, PyObject *lnotab); + +PyAPI_FUNC(int) PyUnstable_Code_GetExtra( + PyObject *code, Py_ssize_t index, void **extra); +PyAPI_FUNC(int) PyUnstable_Code_SetExtra( + PyObject *code, Py_ssize_t index, void *extra); +// Old names -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline int +_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) +{ + return PyUnstable_Code_GetExtra(code, index, extra); +} +_Py_DEPRECATED_EXTERNALLY(3.12) static inline int +_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) +{ + return PyUnstable_Code_SetExtra(code, index, extra); +} + +/* Equivalent to getattr(code, 'co_code') in Python. + Returns a strong reference to a bytes object. */ +PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_varnames') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_cellvars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_freevars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code); + +typedef enum _PyCodeLocationInfoKind { + /* short forms are 0 to 9 */ + PY_CODE_LOCATION_INFO_SHORT0 = 0, + /* one lineforms are 10 to 12 */ + PY_CODE_LOCATION_INFO_ONE_LINE0 = 10, + PY_CODE_LOCATION_INFO_ONE_LINE1 = 11, + PY_CODE_LOCATION_INFO_ONE_LINE2 = 12, + + PY_CODE_LOCATION_INFO_NO_COLUMNS = 13, + PY_CODE_LOCATION_INFO_LONG = 14, + PY_CODE_LOCATION_INFO_NONE = 15 +} _PyCodeLocationInfoKind; + +#ifdef __cplusplus +} +#endif +#endif // !Py_CODE_H +#endif // !Py_LIMITED_API diff --git a/contrib/tools/python3/Include/cpython/compile.h b/contrib/tools/python3/Include/cpython/compile.h new file mode 100644 index 0000000000..f5a62a8ec6 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/compile.h @@ -0,0 +1,69 @@ +#ifndef Py_CPYTHON_COMPILE_H +# error "this header file must not be included directly" +#endif + +/* Public interface */ +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) + +/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. + PyCF_ constants can use bits from 0x0100 to 0x10000. + CO_FUTURE_ constants use bits starting at 0x20000. */ +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 +#define PyCF_IGNORE_COOKIE 0x0800 +#define PyCF_TYPE_COMMENTS 0x1000 +#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000 +#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \ + PyCF_ALLOW_INCOMPLETE_INPUT) + +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ + int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ +} PyCompilerFlags; + +#define _PyCompilerFlags_INIT \ + (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} + +/* source location information */ +typedef struct { + int lineno; + int end_lineno; + int col_offset; + int end_col_offset; +} _PyCompilerSrcLocation; + +#define SRC_LOCATION_FROM_AST(n) \ + (_PyCompilerSrcLocation){ \ + .lineno = (n)->lineno, \ + .end_lineno = (n)->end_lineno, \ + .col_offset = (n)->col_offset, \ + .end_col_offset = (n)->end_col_offset } + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + _PyCompilerSrcLocation ff_location; /* location of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" +#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" +#define FUTURE_GENERATOR_STOP "generator_stop" +#define FUTURE_ANNOTATIONS "annotations" + +#define PY_INVALID_STACK_EFFECT INT_MAX +PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); +PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); diff --git a/contrib/tools/python3/Include/cpython/complexobject.h b/contrib/tools/python3/Include/cpython/complexobject.h new file mode 100644 index 0000000000..b7d7283ae8 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/complexobject.h @@ -0,0 +1,44 @@ +#ifndef Py_CPYTHON_COMPLEXOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; + +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); + +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); + +#ifdef Py_BUILD_CORE +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +extern int _PyComplex_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif // Py_BUILD_CORE diff --git a/contrib/tools/python3/Include/cpython/context.h b/contrib/tools/python3/Include/cpython/context.h new file mode 100644 index 0000000000..9879fc7192 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/context.h @@ -0,0 +1,78 @@ +#ifndef Py_LIMITED_API +#ifndef Py_CONTEXT_H +#define Py_CONTEXT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyContext_Type; +typedef struct _pycontextobject PyContext; + +PyAPI_DATA(PyTypeObject) PyContextVar_Type; +typedef struct _pycontextvarobject PyContextVar; + +PyAPI_DATA(PyTypeObject) PyContextToken_Type; +typedef struct _pycontexttokenobject PyContextToken; + + +#define PyContext_CheckExact(o) Py_IS_TYPE((o), &PyContext_Type) +#define PyContextVar_CheckExact(o) Py_IS_TYPE((o), &PyContextVar_Type) +#define PyContextToken_CheckExact(o) Py_IS_TYPE((o), &PyContextToken_Type) + + +PyAPI_FUNC(PyObject *) PyContext_New(void); +PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *); +PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void); + +PyAPI_FUNC(int) PyContext_Enter(PyObject *); +PyAPI_FUNC(int) PyContext_Exit(PyObject *); + + +/* Create a new context variable. + + default_value can be NULL. +*/ +PyAPI_FUNC(PyObject *) PyContextVar_New( + const char *name, PyObject *default_value); + + +/* Get a value for the variable. + + Returns -1 if an error occurred during lookup. + + Returns 0 if value either was or was not found. + + If value was found, *value will point to it. + If not, it will point to: + + - default_value, if not NULL; + - the default value of "var", if not NULL; + - NULL. + + '*value' will be a new ref, if not NULL. +*/ +PyAPI_FUNC(int) PyContextVar_Get( + PyObject *var, PyObject *default_value, PyObject **value); + + +/* Set a new value for the variable. + Returns NULL if an error occurs. +*/ +PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value); + + +/* Reset a variable to its previous value. + Returns 0 on success, -1 on error. +*/ +PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token); + + +/* This method is exposed only for CPython tests. Don not use it. */ +PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CONTEXT_H */ +#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/descrobject.h b/contrib/tools/python3/Include/cpython/descrobject.h new file mode 100644 index 0000000000..e2ea1b9a2d --- /dev/null +++ b/contrib/tools/python3/Include/cpython/descrobject.h @@ -0,0 +1,64 @@ +#ifndef Py_CPYTHON_DESCROBJECT_H +# error "this header file must not be included directly" +#endif + +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + const char *name; + int offset; + void *function; + wrapperfunc wrapper; + const char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +typedef struct { + PyObject_HEAD + PyTypeObject *d_type; + PyObject *d_name; + PyObject *d_qualname; +} PyDescrObject; + +#define PyDescr_COMMON PyDescrObject d_common + +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; + vectorcallfunc vectorcall; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; + +PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; + +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +PyAPI_FUNC(int) PyDescr_IsData(PyObject *); diff --git a/contrib/tools/python3/Include/cpython/dictobject.h b/contrib/tools/python3/Include/cpython/dictobject.h new file mode 100644 index 0000000000..ddada92202 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/dictobject.h @@ -0,0 +1,118 @@ +#ifndef Py_CPYTHON_DICTOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct _dictkeysobject PyDictKeysObject; +typedef struct _dictvalues PyDictValues; + +/* The ma_values pointer is NULL for a combined table + * or points to an array of PyObject* for a split table + */ +typedef struct { + PyObject_HEAD + + /* Number of items in the dictionary */ + Py_ssize_t ma_used; + + /* Dictionary version: globally unique, value change each time + the dictionary is modified */ +#ifdef Py_BUILD_CORE + uint64_t ma_version_tag; +#else + Py_DEPRECATED(3.12) uint64_t ma_version_tag; +#endif + + PyDictKeysObject *ma_keys; + + /* If ma_values is NULL, the table is "combined": keys and values + are stored in ma_keys. + + If ma_values is not NULL, the table is split: + keys are stored in ma_keys and values are stored in ma_values */ + PyDictValues *ma_values; +} PyDictObject; + +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *dp, PyObject *key); +PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, + _Py_Identifier *key); +PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyDict_SetDefault( + PyObject *mp, PyObject *key, PyObject *defaultobj); +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, + int (*predicate)(PyObject *value)); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); + +/* Get the number of items of a dictionary. */ +static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { + PyDictObject *mp; + assert(PyDict_Check(op)); + mp = _Py_CAST(PyDictObject*, op); + return mp->ma_used; +} +#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) + +PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); +PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); +PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); +PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); +PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); +PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); +PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); +#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) + +/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, + the first occurrence of a key wins, if override is 1, the last occurrence + of a key wins, if override is 2, a KeyError with conflicting key as + argument is raised. +*/ +PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); +PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item); + +PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key); +PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); + +/* _PyDictView */ + +typedef struct { + PyObject_HEAD + PyDictObject *dv_dict; +} _PyDictViewObject; + +PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); + +/* Dictionary watchers */ + +#define PY_FOREACH_DICT_EVENT(V) \ + V(ADDED) \ + V(MODIFIED) \ + V(DELETED) \ + V(CLONED) \ + V(CLEARED) \ + V(DEALLOCATED) + +typedef enum { + #define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT, + PY_FOREACH_DICT_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyDict_WatchEvent; + +// Callback to be invoked when a watched dict is cleared, dealloced, or modified. +// In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the +// new value for key, NULL if key is being deleted. +typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value); + +// Register/unregister a dict-watcher callback +PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback); +PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id); + +// Mark given dictionary as "watched" (callback will be called if it is modified) +PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict); +PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict); diff --git a/contrib/tools/python3/Include/cpython/fileobject.h b/contrib/tools/python3/Include/cpython/fileobject.h new file mode 100644 index 0000000000..b70ec31898 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/fileobject.h @@ -0,0 +1,19 @@ +#ifndef Py_CPYTHON_FILEOBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +PyAPI_FUNC(char *) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*); + +/* The std printer acts as a preliminary sys.stderr until the new io + infrastructure is in place. */ +PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); +PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; + +typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); + +PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); +PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); +PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); + +PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); diff --git a/contrib/tools/python3/Include/cpython/fileutils.h b/contrib/tools/python3/Include/cpython/fileutils.h new file mode 100644 index 0000000000..b386ad107b --- /dev/null +++ b/contrib/tools/python3/Include/cpython/fileutils.h @@ -0,0 +1,8 @@ +#ifndef Py_CPYTHON_FILEUTILS_H +# error "this header file must not be included directly" +#endif + +// Used by _testcapi which must not use the internal C API +PyAPI_FUNC(FILE*) _Py_fopen_obj( + PyObject *path, + const char *mode); diff --git a/contrib/tools/python3/Include/cpython/floatobject.h b/contrib/tools/python3/Include/cpython/floatobject.h new file mode 100644 index 0000000000..127093098b --- /dev/null +++ b/contrib/tools/python3/Include/cpython/floatobject.h @@ -0,0 +1,27 @@ +#ifndef Py_CPYTHON_FLOATOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + PyObject_HEAD + double ob_fval; +} PyFloatObject; + +#define _PyFloat_CAST(op) \ + (assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op)) + +// Static inline version of PyFloat_AsDouble() trading safety for speed. +// It doesn't check if op is a double object. +static inline double PyFloat_AS_DOUBLE(PyObject *op) { + return _PyFloat_CAST(op)->ob_fval; +} +#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op)) + + +PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le); + +PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le); diff --git a/contrib/tools/python3/Include/cpython/frameobject.h b/contrib/tools/python3/Include/cpython/frameobject.h new file mode 100644 index 0000000000..4e19535c65 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/frameobject.h @@ -0,0 +1,29 @@ +/* Frame object interface */ + +#ifndef Py_CPYTHON_FRAMEOBJECT_H +# error "this header file must not be included directly" +#endif + +/* Standard object interface */ + +PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + +/* The rest of the interface is specific for frame objects */ + +/* Conversions between "fast locals" and locals in dictionary */ + +PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); + +/* -- Caveat emptor -- + * The concept of entry frames is an implementation detail of the CPython + * interpreter. This API is considered unstable and is provided for the + * convenience of debuggers, profilers and state-inspecting tools. Notice that + * this API can be changed in future minor versions if the underlying frame + * mechanism change or the concept of an 'entry frame' or its semantics becomes + * obsolete or outdated. */ + +PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame); + +PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); +PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); diff --git a/contrib/tools/python3/Include/cpython/funcobject.h b/contrib/tools/python3/Include/cpython/funcobject.h new file mode 100644 index 0000000000..6f78f5868d --- /dev/null +++ b/contrib/tools/python3/Include/cpython/funcobject.h @@ -0,0 +1,188 @@ +/* Function object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_FUNCOBJECT_H +#define Py_FUNCOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +#define COMMON_FIELDS(PREFIX) \ + PyObject *PREFIX ## globals; \ + PyObject *PREFIX ## builtins; \ + PyObject *PREFIX ## name; \ + PyObject *PREFIX ## qualname; \ + PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \ + PyObject *PREFIX ## defaults; /* NULL or a tuple */ \ + PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \ + PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */ + +typedef struct { + COMMON_FIELDS(fc_) +} PyFrameConstructor; + +/* Function objects and code objects should not be confused with each other: + * + * Function objects are created by the execution of the 'def' statement. + * They reference a code object in their __code__ attribute, which is a + * purely syntactic object, i.e. nothing more than a compiled version of some + * source code lines. There is one code object per source code "fragment", + * but each code object can be referenced by zero or many function objects + * depending only on how many times the 'def' statement in the source was + * executed so far. + */ + +typedef struct { + PyObject_HEAD + COMMON_FIELDS(func_) + PyObject *func_doc; /* The __doc__ attribute, can be anything */ + PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ + PyObject *func_weakreflist; /* List of weak references */ + PyObject *func_module; /* The __module__ attribute, can be anything */ + PyObject *func_annotations; /* Annotations, a dict or NULL */ + PyObject *func_typeparams; /* Tuple of active type variables or NULL */ + vectorcallfunc vectorcall; + /* Version number for use by specializer. + * Can set to non-zero when we want to specialize. + * Will be set to zero if any of these change: + * defaults + * kwdefaults (only if the object changes, not the contents of the dict) + * code + * annotations + * vectorcall function pointer */ + uint32_t func_version; + + /* Invariant: + * func_closure contains the bindings for func_code->co_freevars, so + * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) + * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). + */ +} PyFunctionObject; + +PyAPI_DATA(PyTypeObject) PyFunction_Type; + +#define PyFunction_Check(op) Py_IS_TYPE((op), &PyFunction_Type) + +PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(void) PyFunction_SetVectorcall(PyFunctionObject *, vectorcallfunc); +PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); +PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *); +PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( + PyObject *func, + PyObject *const *stack, + size_t nargsf, + PyObject *kwnames); + +#define _PyFunction_CAST(func) \ + (assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func)) + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyFunction_GET_CODE(PyObject *func) { + return _PyFunction_CAST(func)->func_code; +} +#define PyFunction_GET_CODE(func) PyFunction_GET_CODE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_GLOBALS(PyObject *func) { + return _PyFunction_CAST(func)->func_globals; +} +#define PyFunction_GET_GLOBALS(func) PyFunction_GET_GLOBALS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_MODULE(PyObject *func) { + return _PyFunction_CAST(func)->func_module; +} +#define PyFunction_GET_MODULE(func) PyFunction_GET_MODULE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_defaults; +} +#define PyFunction_GET_DEFAULTS(func) PyFunction_GET_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_KW_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_kwdefaults; +} +#define PyFunction_GET_KW_DEFAULTS(func) PyFunction_GET_KW_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_CLOSURE(PyObject *func) { + return _PyFunction_CAST(func)->func_closure; +} +#define PyFunction_GET_CLOSURE(func) PyFunction_GET_CLOSURE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_ANNOTATIONS(PyObject *func) { + return _PyFunction_CAST(func)->func_annotations; +} +#define PyFunction_GET_ANNOTATIONS(func) PyFunction_GET_ANNOTATIONS(_PyObject_CAST(func)) + +/* The classmethod and staticmethod types lives here, too */ +PyAPI_DATA(PyTypeObject) PyClassMethod_Type; +PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; + +PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); + +#define PY_FOREACH_FUNC_EVENT(V) \ + V(CREATE) \ + V(DESTROY) \ + V(MODIFY_CODE) \ + V(MODIFY_DEFAULTS) \ + V(MODIFY_KWDEFAULTS) + +typedef enum { + #define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, + PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyFunction_WatchEvent; + +/* + * A callback that is invoked for different events in a function's lifecycle. + * + * The callback is invoked with a borrowed reference to func, after it is + * created and before it is modified or destroyed. The callback should not + * modify func. + * + * When a function's code object, defaults, or kwdefaults are modified the + * callback will be invoked with the respective event and new_value will + * contain a borrowed reference to the new value that is about to be stored in + * the function. Otherwise the third argument is NULL. + * + * If the callback returns with an exception set, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyFunction_WatchCallback)( + PyFunction_WatchEvent event, + PyFunctionObject *func, + PyObject *new_value); + +/* + * Register a per-interpreter callback that will be invoked for function lifecycle + * events. + * + * Returns a handle that may be passed to PyFunction_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyFunction_AddWatcher(PyFunction_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the supplied id. + */ +PyAPI_FUNC(int) PyFunction_ClearWatcher(int watcher_id); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FUNCOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/genobject.h b/contrib/tools/python3/Include/cpython/genobject.h new file mode 100644 index 0000000000..7856481b5d --- /dev/null +++ b/contrib/tools/python3/Include/cpython/genobject.h @@ -0,0 +1,89 @@ +/* Generator object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_GENOBJECT_H +#define Py_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Generators --------------------------------------------------------- */ + +/* _PyGenObject_HEAD defines the initial segment of generator + and coroutine objects. */ +#define _PyGenObject_HEAD(prefix) \ + PyObject_HEAD \ + /* List of weak reference. */ \ + PyObject *prefix##_weakreflist; \ + /* Name of the generator. */ \ + PyObject *prefix##_name; \ + /* Qualified name of the generator. */ \ + PyObject *prefix##_qualname; \ + _PyErr_StackItem prefix##_exc_state; \ + PyObject *prefix##_origin_or_finalizer; \ + char prefix##_hooks_inited; \ + char prefix##_closed; \ + char prefix##_running_async; \ + /* The frame */ \ + int8_t prefix##_frame_state; \ + PyObject *prefix##_iframe[1]; \ + +typedef struct { + /* The gi_ prefix is intended to remind of generator-iterator. */ + _PyGenObject_HEAD(gi) +} PyGenObject; + +PyAPI_DATA(PyTypeObject) PyGen_Type; + +#define PyGen_Check(op) PyObject_TypeCheck((op), &PyGen_Type) +#define PyGen_CheckExact(op) Py_IS_TYPE((op), &PyGen_Type) + +PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *); +PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, + PyObject *name, PyObject *qualname); +PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); +PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); +PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); +PyAPI_FUNC(PyCodeObject *) PyGen_GetCode(PyGenObject *gen); + + +/* --- PyCoroObject ------------------------------------------------------- */ + +typedef struct { + _PyGenObject_HEAD(cr) +} PyCoroObject; + +PyAPI_DATA(PyTypeObject) PyCoro_Type; +PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; + +#define PyCoro_CheckExact(op) Py_IS_TYPE((op), &PyCoro_Type) +PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, + PyObject *name, PyObject *qualname); + + +/* --- Asynchronous Generators -------------------------------------------- */ + +typedef struct { + _PyGenObject_HEAD(ag) +} PyAsyncGenObject; + +PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; + +PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, + PyObject *name, PyObject *qualname); + +#define PyAsyncGen_CheckExact(op) Py_IS_TYPE((op), &PyAsyncGen_Type) + +#define PyAsyncGenASend_CheckExact(op) Py_IS_TYPE((op), &_PyAsyncGenASend_Type) + + +#undef _PyGenObject_HEAD + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GENOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/import.h b/contrib/tools/python3/Include/cpython/import.h new file mode 100644 index 0000000000..2bca4ade4c --- /dev/null +++ b/contrib/tools/python3/Include/cpython/import.h @@ -0,0 +1,46 @@ +#ifndef Py_CPYTHON_IMPORT_H +# error "this header file must not be included directly" +#endif + +PyMODINIT_FUNC PyInit__imp(void); + +PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); + +PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name); +PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); +PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); + +PyAPI_FUNC(void) _PyImport_AcquireLock(PyInterpreterState *interp); +PyAPI_FUNC(int) _PyImport_ReleaseLock(PyInterpreterState *interp); + +PyAPI_FUNC(int) _PyImport_FixupBuiltin( + PyObject *mod, + const char *name, /* UTF-8 encoded string */ + PyObject *modules + ); +PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, + PyObject *, PyObject *); + +struct _inittab { + const char *name; /* ASCII encoded string */ + PyObject* (*initfunc)(void); +}; +// This is not used after Py_Initialize() is called. +PyAPI_DATA(struct _inittab *) PyImport_Inittab; +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); + +struct _frozen { + const char *name; /* ASCII encoded string */ + const unsigned char *code; + int size; + int is_package; + PyObject *(*get_code)(void); +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; + +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *); +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *); diff --git a/contrib/tools/python3/Include/cpython/initconfig.h b/contrib/tools/python3/Include/cpython/initconfig.h new file mode 100644 index 0000000000..cbae97f12f --- /dev/null +++ b/contrib/tools/python3/Include/cpython/initconfig.h @@ -0,0 +1,256 @@ +#ifndef Py_PYCORECONFIG_H +#define Py_PYCORECONFIG_H +#ifndef Py_LIMITED_API +#ifdef __cplusplus +extern "C" { +#endif + +/* --- PyStatus ----------------------------------------------- */ + +typedef struct { + enum { + _PyStatus_TYPE_OK=0, + _PyStatus_TYPE_ERROR=1, + _PyStatus_TYPE_EXIT=2 + } _type; + const char *func; + const char *err_msg; + int exitcode; +} PyStatus; + +PyAPI_FUNC(PyStatus) PyStatus_Ok(void); +PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg); +PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void); +PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); +PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); +PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); +PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); +PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status); + +/* --- PyWideStringList ------------------------------------------------ */ + +typedef struct { + /* If length is greater than zero, items must be non-NULL + and all items strings must be non-NULL */ + Py_ssize_t length; + wchar_t **items; +} PyWideStringList; + +PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list, + const wchar_t *item); +PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list, + Py_ssize_t index, + const wchar_t *item); + + +/* --- PyPreConfig ----------------------------------------------- */ + +typedef struct PyPreConfig { + int _config_init; /* _PyConfigInitEnum value */ + + /* Parse Py_PreInitializeFromBytesArgs() arguments? + See PyConfig.parse_argv */ + int parse_argv; + + /* If greater than 0, enable isolated mode: sys.path contains + neither the script's directory nor the user's site-packages directory. + + Set to 1 by the -I command line option. If set to -1 (default), inherit + Py_IsolatedFlag value. */ + int isolated; + + /* If greater than 0: use environment variables. + Set to 0 by -E command line option. If set to -1 (default), it is + set to !Py_IgnoreEnvironmentFlag. */ + int use_environment; + + /* Set the LC_CTYPE locale to the user preferred locale? If equals to 0, + set coerce_c_locale and coerce_c_locale_warn to 0. */ + int configure_locale; + + /* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538) + + Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1. + Set to 2 if the user preferred LC_CTYPE locale is "C". + + If it is equal to 1, LC_CTYPE locale is read to decide if it should be + coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2 + if the LC_CTYPE locale must be coerced. + + Disable by default (set to 0). Set it to -1 to let Python decide if it + should be enabled or not. */ + int coerce_c_locale; + + /* Emit a warning if the LC_CTYPE locale is coerced? + + Set to 1 by PYTHONCOERCECLOCALE=warn. + + Disable by default (set to 0). Set it to -1 to let Python decide if it + should be enabled or not. */ + int coerce_c_locale_warn; + +#ifdef MS_WINDOWS + /* If greater than 1, use the "mbcs" encoding instead of the UTF-8 + encoding for the filesystem encoding. + + Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is + set to a non-empty string. If set to -1 (default), inherit + Py_LegacyWindowsFSEncodingFlag value. + + See PEP 529 for more details. */ + int legacy_windows_fs_encoding; +#endif + + /* Enable UTF-8 mode? (PEP 540) + + Disabled by default (equals to 0). + + Set to 1 by "-X utf8" and "-X utf8=1" command line options. + Set to 1 by PYTHONUTF8=1 environment variable. + + Set to 0 by "-X utf8=0" and PYTHONUTF8=0. + + If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or + "POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */ + int utf8_mode; + + /* If non-zero, enable the Python Development Mode. + + Set to 1 by the -X dev command line option. Set by the PYTHONDEVMODE + environment variable. */ + int dev_mode; + + /* Memory allocator: PYTHONMALLOC env var. + See PyMemAllocatorName for valid values. */ + int allocator; +} PyPreConfig; + +PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config); +PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config); + + +/* --- PyConfig ---------------------------------------------- */ + +/* This structure is best documented in the Doc/c-api/init_config.rst file. */ +typedef struct PyConfig { + int _config_init; /* _PyConfigInitEnum value */ + + int isolated; + int use_environment; + int dev_mode; + int install_signal_handlers; + int use_hash_seed; + unsigned long hash_seed; + int faulthandler; + int tracemalloc; + int perf_profiling; + int import_time; + int code_debug_ranges; + int show_ref_count; + int dump_refs; + wchar_t *dump_refs_file; + int malloc_stats; + wchar_t *filesystem_encoding; + wchar_t *filesystem_errors; + wchar_t *pycache_prefix; + int parse_argv; + PyWideStringList orig_argv; + PyWideStringList argv; + PyWideStringList xoptions; + PyWideStringList warnoptions; + int site_import; + int bytes_warning; + int warn_default_encoding; + int inspect; + int interactive; + int optimization_level; + int parser_debug; + int write_bytecode; + int verbose; + int quiet; + int user_site_directory; + int configure_c_stdio; + int buffered_stdio; + wchar_t *stdio_encoding; + wchar_t *stdio_errors; +#ifdef MS_WINDOWS + int legacy_windows_stdio; +#endif + wchar_t *check_hash_pycs_mode; + int use_frozen_modules; + int safe_path; + int int_max_str_digits; + + /* --- Path configuration inputs ------------ */ + int pathconfig_warnings; + wchar_t *program_name; + wchar_t *pythonpath_env; + wchar_t *home; + wchar_t *platlibdir; + + /* --- Path configuration outputs ----------- */ + int module_search_paths_set; + PyWideStringList module_search_paths; + wchar_t *stdlib_dir; + wchar_t *executable; + wchar_t *base_executable; + wchar_t *prefix; + wchar_t *base_prefix; + wchar_t *exec_prefix; + wchar_t *base_exec_prefix; + + /* --- Parameter only used by Py_Main() ---------- */ + int skip_source_first_line; + wchar_t *run_command; + wchar_t *run_module; + wchar_t *run_filename; + + /* --- Private fields ---------------------------- */ + + // Install importlib? If equals to 0, importlib is not initialized at all. + // Needed by freeze_importlib. + int _install_importlib; + + // If equal to 0, stop Python initialization before the "main" phase. + int _init_main; + + // If non-zero, we believe we're running from a source tree. + int _is_python_build; +} PyConfig; + +PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); +PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config); +PyAPI_FUNC(void) PyConfig_Clear(PyConfig *); +PyAPI_FUNC(PyStatus) PyConfig_SetString( + PyConfig *config, + wchar_t **config_str, + const wchar_t *str); +PyAPI_FUNC(PyStatus) PyConfig_SetBytesString( + PyConfig *config, + wchar_t **config_str, + const char *str); +PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config); +PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv( + PyConfig *config, + Py_ssize_t argc, + char * const *argv); +PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config, + Py_ssize_t argc, + wchar_t * const *argv); +PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, + PyWideStringList *list, + Py_ssize_t length, wchar_t **items); + + +/* --- Helper functions --------------------------------------- */ + +/* Get the original command line arguments, before Python modified them. + + See also PyConfig.orig_argv. */ +PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LIMITED_API */ +#endif /* !Py_PYCORECONFIG_H */ diff --git a/contrib/tools/python3/Include/cpython/interpreteridobject.h b/contrib/tools/python3/Include/cpython/interpreteridobject.h new file mode 100644 index 0000000000..5076584209 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/interpreteridobject.h @@ -0,0 +1,11 @@ +#ifndef Py_CPYTHON_INTERPRETERIDOBJECT_H +# error "this header file must not be included directly" +#endif + +/* Interpreter ID Object */ + +PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; + +PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); +PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); diff --git a/contrib/tools/python3/Include/cpython/listobject.h b/contrib/tools/python3/Include/cpython/listobject.h new file mode 100644 index 0000000000..8fa82122d8 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/listobject.h @@ -0,0 +1,47 @@ +#ifndef Py_CPYTHON_LISTOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; + +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); +PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); + +/* Cast argument to PyListObject* type. */ +#define _PyList_CAST(op) \ + (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op))) + +// Macros and static inline functions, trading safety for speed + +static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) { + PyListObject *list = _PyList_CAST(op); + return Py_SIZE(list); +} +#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) + +#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)]) + +static inline void +PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { + PyListObject *list = _PyList_CAST(op); + list->ob_item[index] = value; +} +#define PyList_SET_ITEM(op, index, value) \ + PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) diff --git a/contrib/tools/python3/Include/cpython/longintrepr.h b/contrib/tools/python3/Include/cpython/longintrepr.h new file mode 100644 index 0000000000..692c69ba76 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/longintrepr.h @@ -0,0 +1,132 @@ +#ifndef Py_LIMITED_API +#ifndef Py_LONGINTREPR_H +#define Py_LONGINTREPR_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is published for the benefit of "friends" marshal.c and _decimal.c. */ + +/* Parameters of the integer representation. There are two different + sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit + integer type, and one set for 15-bit digits with each digit stored in an + unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at + configure time or in pyport.h, is used to decide which digit size to use. + + Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits' + should be an unsigned integer type able to hold all integers up to + PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type, + and that overflow is handled by taking the result modulo 2**N for some N > + PyLong_SHIFT. The majority of the code doesn't care about the precise + value of PyLong_SHIFT, but there are some notable exceptions: + + - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 + + - long_hash() requires that PyLong_SHIFT is *strictly* less than the number + of bits in an unsigned long, as do the PyLong <-> long (or unsigned long) + conversion functions + + - the Python int <-> size_t/Py_ssize_t conversion functions expect that + PyLong_SHIFT is strictly less than the number of bits in a size_t + + - the marshal code currently expects that PyLong_SHIFT is a multiple of 15 + + - NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single + digit; with the current values this forces PyLong_SHIFT >= 9 + + The values 15 and 30 should fit all of the above requirements, on any + platform. +*/ + +#if PYLONG_BITS_IN_DIGIT == 30 +typedef uint32_t digit; +typedef int32_t sdigit; /* signed variant of digit */ +typedef uint64_t twodigits; +typedef int64_t stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 30 +#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ +#elif PYLONG_BITS_IN_DIGIT == 15 +typedef unsigned short digit; +typedef short sdigit; /* signed variant of digit */ +typedef unsigned long twodigits; +typedef long stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 15 +#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ +#else +#error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif +#define PyLong_BASE ((digit)1 << PyLong_SHIFT) +#define PyLong_MASK ((digit)(PyLong_BASE - 1)) + +/* Long integer representation. + The absolute value of a number is equal to + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + Negative numbers are represented with ob_size < 0; + zero is represented by ob_size == 0. + In a normalized number, ob_digit[abs(ob_size)-1] (the most significant + digit) is never zero. Also, in all cases, for all valid i, + 0 <= ob_digit[i] <= MASK. + The allocation function takes care of allocating extra memory + so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + We always allocate memory for at least one digit, so accessing ob_digit[0] + is always safe. However, in the case ob_size == 0, the contents of + ob_digit[0] may be undefined. + + CAUTION: Generic code manipulating subtypes of PyVarObject has to + aware that ints abuse ob_size's sign bit. +*/ + +typedef struct _PyLongValue { + uintptr_t lv_tag; /* Number of digits, sign and flags */ + digit ob_digit[1]; +} _PyLongValue; + +struct _longobject { + PyObject_HEAD + _PyLongValue long_value; +}; + +PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); + +/* Return a copy of src. */ +PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); + +PyAPI_FUNC(PyLongObject *) +_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits); + + +/* Inline some internals for speed. These should be in pycore_long.h + * if user code didn't need them inlined. */ + +#define _PyLong_SIGN_MASK 3 +#define _PyLong_NON_SIZE_BITS 3 + + +static inline int +_PyLong_IsCompact(const PyLongObject* op) { + assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS)); + return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS); +} + +#define PyUnstable_Long_IsCompact _PyLong_IsCompact + +static inline Py_ssize_t +_PyLong_CompactValue(const PyLongObject *op) +{ + assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS)); + assert(PyUnstable_Long_IsCompact(op)); + Py_ssize_t sign = 1 - (op->long_value.lv_tag & _PyLong_SIGN_MASK); + return sign * (Py_ssize_t)op->long_value.ob_digit[0]; +} + +#define PyUnstable_Long_CompactValue _PyLong_CompactValue + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGINTREPR_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/longobject.h b/contrib/tools/python3/Include/cpython/longobject.h new file mode 100644 index 0000000000..90cc0f267a --- /dev/null +++ b/contrib/tools/python3/Include/cpython/longobject.h @@ -0,0 +1,100 @@ +#ifndef Py_CPYTHON_LONGOBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); + +PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); + +/* _PyLong_Frexp returns a double x and an exponent e such that the + true value is approximately equal to x * 2**e. e is >= 0. x is + 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is + possible if the number of bits doesn't fit into a Py_ssize_t, sets + OverflowError and returns -1.0 for x, 0 for e. */ +PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); + +PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); +PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); + +/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. + v must not be NULL, and must be a normalized long. + There are no error cases. +*/ +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + +/* _PyLong_NumBits. Return the number of bits needed to represent the + absolute value of a long. For example, this returns 1 for 1 and -1, 2 + for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. +*/ +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest + integer q to the exact quotient a / b, rounding to the nearest even integer + in the case of a tie. Return (q, r), where r = a - q*b. The remainder r + will satisfy abs(r) <= abs(b)/2, with equality possible only if q is + even. +*/ +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); + +/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python int with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python int. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-significant n bytes of the true value. +*/ +PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_Format: Convert the long to a string object with given base, + appending a base prefix of 0[box] if base is 2, 8 or 16. */ +PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); + +/* For use by the gcd function in mathmodule.c */ +PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); +PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); + + +PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op); +PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op); + diff --git a/contrib/tools/python3/Include/cpython/memoryobject.h b/contrib/tools/python3/Include/cpython/memoryobject.h new file mode 100644 index 0000000000..3837fa8c6a --- /dev/null +++ b/contrib/tools/python3/Include/cpython/memoryobject.h @@ -0,0 +1,52 @@ +#ifndef Py_CPYTHON_MEMORYOBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; + +/* The structs are declared here so that macros can work, but they shouldn't + be considered public. Don't access their fields directly, use the macros + and functions instead! */ +#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ +#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ + +typedef struct { + PyObject_HEAD + int flags; /* state flags */ + Py_ssize_t exports; /* number of direct memoryview exports */ + Py_buffer master; /* snapshot buffer obtained from the original exporter */ +} _PyManagedBufferObject; + + +/* memoryview state flags */ +#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ +#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ +#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ +#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ +#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ +#define _Py_MEMORYVIEW_RESTRICTED 0x020 /* Disallow new references to the memoryview's buffer */ + +typedef struct { + PyObject_VAR_HEAD + _PyManagedBufferObject *mbuf; /* managed buffer */ + Py_hash_t hash; /* hash value for read-only views */ + int flags; /* state flags */ + Py_ssize_t exports; /* number of buffer re-exports */ + Py_buffer view; /* private copy of the exporter's view */ + PyObject *weakreflist; + Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ +} PyMemoryViewObject; + +#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op) + +/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ +static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) { + return (&_PyMemoryView_CAST(op)->view); +} +#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op)) + +/* Get a pointer to the exporting object (this may be NULL!). */ +static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) { + return _PyMemoryView_CAST(op)->view.obj; +} +#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op)) diff --git a/contrib/tools/python3/Include/cpython/methodobject.h b/contrib/tools/python3/Include/cpython/methodobject.h new file mode 100644 index 0000000000..d541e15494 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/methodobject.h @@ -0,0 +1,66 @@ +#ifndef Py_CPYTHON_METHODOBJECT_H +# error "this header file must not be included directly" +#endif + +// PyCFunctionObject structure + +typedef struct { + PyObject_HEAD + PyMethodDef *m_ml; /* Description of the C function to call */ + PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ + PyObject *m_module; /* The __module__ attribute, can be anything */ + PyObject *m_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; +} PyCFunctionObject; + +#define _PyCFunctionObject_CAST(func) \ + (assert(PyCFunction_Check(func)), \ + _Py_CAST(PyCFunctionObject*, (func))) + + +// PyCMethodObject structure + +typedef struct { + PyCFunctionObject func; + PyTypeObject *mm_class; /* Class that defines this method */ +} PyCMethodObject; + +#define _PyCMethodObject_CAST(func) \ + (assert(PyCMethod_Check(func)), \ + _Py_CAST(PyCMethodObject*, (func))) + +PyAPI_DATA(PyTypeObject) PyCMethod_Type; + +#define PyCMethod_CheckExact(op) Py_IS_TYPE((op), &PyCMethod_Type) +#define PyCMethod_Check(op) PyObject_TypeCheck((op), &PyCMethod_Type) + + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) { + return _PyCFunctionObject_CAST(func)->m_ml->ml_meth; +} +#define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func)) + +static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { + PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); + if (func->m_ml->ml_flags & METH_STATIC) { + return _Py_NULL; + } + return func->m_self; +} +#define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func)) + +static inline int PyCFunction_GET_FLAGS(PyObject *func) { + return _PyCFunctionObject_CAST(func)->m_ml->ml_flags; +} +#define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func)) + +static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { + PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); + if (func->m_ml->ml_flags & METH_METHOD) { + return _PyCMethodObject_CAST(func)->mm_class; + } + return _Py_NULL; +} +#define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func)) diff --git a/contrib/tools/python3/Include/cpython/modsupport.h b/contrib/tools/python3/Include/cpython/modsupport.h new file mode 100644 index 0000000000..2259291aff --- /dev/null +++ b/contrib/tools/python3/Include/cpython/modsupport.h @@ -0,0 +1,109 @@ +#ifndef Py_CPYTHON_MODSUPPORT_H +# error "this header file must not be included directly" +#endif + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define _Py_VaBuildStack _Py_VaBuildStack_SizeT +#else +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif + +PyAPI_FUNC(int) _PyArg_UnpackStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *name, + Py_ssize_t min, + Py_ssize_t max, + ...); + +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); +#define _PyArg_NoKeywords(funcname, kwargs) \ + ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) +#define _PyArg_NoKwnames(funcname, kwnames) \ + ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) +#define _PyArg_NoPositional(funcname, args) \ + ((args) == NULL || _PyArg_NoPositional((funcname), (args))) + +#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX) + +PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); +PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, + Py_ssize_t, Py_ssize_t); +#define _PyArg_CheckPositional(funcname, nargs, min, max) \ + ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ + || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) + +PyAPI_FUNC(PyObject **) _Py_VaBuildStack( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); + +typedef struct _PyArg_Parser { + int initialized; + const char *format; + const char * const *keywords; + const char *fname; + const char *custom_msg; + int pos; /* number of positional-only arguments */ + int min; /* minimal number of arguments */ + int max; /* maximal number of positional arguments */ + PyObject *kwtuple; /* tuple of keyword parameter names */ + struct _PyArg_Parser *next; +} _PyArg_Parser; + +#ifdef PY_SSIZE_T_CLEAN +#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT +#define _PyArg_ParseStack _PyArg_ParseStack_SizeT +#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT +#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT +#endif + +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *, + ...); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + PyObject **buf); + +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + int vararg, PyObject **buf); + +#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ + (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ + (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ + _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ + (minpos), (maxpos), (minkw), (buf))) + +PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver); +PyAPI_FUNC(int) _PyModule_Add(PyObject *, const char *, PyObject *); diff --git a/contrib/tools/python3/Include/cpython/object.h b/contrib/tools/python3/Include/cpython/object.h new file mode 100644 index 0000000000..ae7f780a93 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/object.h @@ -0,0 +1,575 @@ +#ifndef Py_CPYTHON_OBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(void) _Py_NewReference(PyObject *op); +PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op); + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +#endif + +#ifdef Py_REF_DEBUG +/* These are useful as debugging aids when chasing down refleaks. */ +PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void); +# define _Py_GetRefTotal() _Py_GetGlobalRefTotal() +PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void); +PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *); +#endif + + +/********************* String Literals ****************************************/ +/* This structure helps managing static strings. The basic usage goes like this: + Instead of doing + + r = PyObject_CallMethod(o, "foo", "args", ...); + + do + + _Py_IDENTIFIER(foo); + ... + r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); + + PyId_foo is a static variable, either on block level or file level. On first + usage, the string "foo" is interned, and the structures are linked. On interpreter + shutdown, all strings are released. + + Alternatively, _Py_static_string allows choosing the variable name. + _PyUnicode_FromId returns a borrowed reference to the interned string. + _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. +*/ +typedef struct _Py_Identifier { + const char* string; + // Index in PyInterpreterState.unicode.ids.array. It is process-wide + // unique and must be initialized to -1. + Py_ssize_t index; +} _Py_Identifier; + +#ifndef Py_BUILD_CORE +// For now we are keeping _Py_IDENTIFIER for continued use +// in non-builtin extensions (and naughty PyPI modules). + +#define _Py_static_string_init(value) { .string = (value), .index = -1 } +#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) +#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + +#endif /* !Py_BUILD_CORE */ + +typedef struct { + /* Number implementations must check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_bool; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + unaryfunc nb_int; + void *nb_reserved; /* the slot formerly known as nb_long */ + unaryfunc nb_float; + + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + void *was_sq_slice; + ssizeobjargproc sq_ass_item; + void *was_sq_ass_slice; + objobjproc sq_contains; + + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result); + +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + sendfunc am_send; +} PyAsyncMethods; + +typedef struct { + getbufferproc bf_getbuffer; + releasebufferproc bf_releasebuffer; +} PyBufferProcs; + +/* Allow printfunc in the tp_vectorcall_offset slot for + * backwards-compatibility */ +typedef Py_ssize_t printfunc; + +// If this structure is modified, Doc/includes/typestruct.h should be updated +// as well. +struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "<module>.<name>" */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + Py_ssize_t tp_vectorcall_offset; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) + or tp_reserved (Python 3) */ + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + unsigned long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + PyMethodDef *tp_methods; + PyMemberDef *tp_members; + PyGetSetDef *tp_getset; + // Strong reference on a heap type, borrowed reference on a static type + PyTypeObject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; /* no longer used */ + void *tp_subclasses; /* for static builtin types this is an index */ + PyObject *tp_weaklist; /* not used for static builtin types */ + destructor tp_del; + + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + + destructor tp_finalize; + vectorcallfunc tp_vectorcall; + + /* bitset of which type-watchers care about this type */ + unsigned char tp_watched; +}; + +/* This struct is used by the specializer + * It should should be treated as an opaque blob + * by code other than the specializer and interpreter. */ +struct _specialization_cache { + // In order to avoid bloating the bytecode with lots of inline caches, the + // members of this structure have a somewhat unique contract. They are set + // by the specialization machinery, and are invalidated by PyType_Modified. + // The rules for using them are as follows: + // - If getitem is non-NULL, then it is the same Python function that + // PyType_Lookup(cls, "__getitem__") would return. + // - If getitem is NULL, then getitem_version is meaningless. + // - If getitem->func_version == getitem_version, then getitem can be called + // with two positional arguments and no keyword arguments, and has neither + // *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM): + PyObject *getitem; + uint32_t getitem_version; +}; + +/* The *real* layout of a type object when allocated on the heap */ +typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject ht_type; + PyAsyncMethods as_async; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots, *ht_qualname; + struct _dictkeysobject *ht_cached_keys; + PyObject *ht_module; + char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec + struct _specialization_cache _spec_cache; // For use by the specializer. + /* here are optional user slots, followed by the members. */ +} PyHeapTypeObject; + +PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); +#ifndef Py_BUILD_CORE +// Backward compatibility for 3rd-party extensions +// that may be using the old name. +#define _PyObject_LookupSpecial _PyObject_LookupSpecialId +#endif +PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *); +PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *); + +PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); +PyAPI_FUNC(void) _Py_BreakPoint(void); +PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); + +PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); +PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); +/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which + don't raise AttributeError. + + Return 1 and set *result != NULL if an attribute is found. + Return 0 and set *result == NULL if an attribute is not found; + an AttributeError is silenced. + Return -1 and set *result == NULL if an error other than AttributeError + is raised. +*/ +PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); +PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **); + +PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); +PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); +PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); + +/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes + dict as the last parameter. */ +PyAPI_FUNC(PyObject *) +_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); +PyAPI_FUNC(int) +_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, + PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); + +/* Safely decref `dst` and set `dst` to `src`. + * + * As in case of Py_CLEAR "the obvious" code can be deadly: + * + * Py_DECREF(dst); + * dst = src; + * + * The safe way is: + * + * Py_SETREF(dst, src); + * + * That arranges to set `dst` to `src` _before_ decref'ing, so that any code + * triggered as a side-effect of `dst` getting torn down no longer believes + * `dst` points to a valid object. + * + * Temporary variables are used to only evalutate macro arguments once and so + * avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to + * avoid a miscompilation caused by type punning. See Py_CLEAR() comment for + * implementation details about type punning. + * + * The memcpy() implementation does not emit a compiler warning if 'src' has + * not the same type than 'src': any pointer type is accepted for 'src'. + */ +#ifdef _Py_TYPEOF +#define Py_SETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_DECREF(_tmp_old_dst); \ + } while (0) +#else +#define Py_SETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_DECREF(_tmp_old_dst); \ + } while (0) +#endif + +/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of + * Py_DECREF(). + */ +#ifdef _Py_TYPEOF +#define Py_XSETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_XDECREF(_tmp_old_dst); \ + } while (0) +#else +#define Py_XSETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_XDECREF(_tmp_old_dst); \ + } while (0) +#endif + + +PyAPI_DATA(PyTypeObject) _PyNone_Type; +PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; + +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; + +PyAPI_FUNC(void) +_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, + size_t sizeof_block); +PyAPI_FUNC(void) +_PyObject_DebugTypeStats(FILE *out); + +/* Define a pair of assertion macros: + _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). + + These work like the regular C assert(), in that they will abort the + process with a message on stderr if the given condition fails to hold, + but compile away to nothing if NDEBUG is defined. + + However, before aborting, Python will also try to call _PyObject_Dump() on + the given object. This may be of use when investigating bugs in which a + particular object is corrupt (e.g. buggy a tp_visit method in an extension + module breaking the garbage collector), to help locate the broken objects. + + The WITH_MSG variant allows you to supply an additional message that Python + will attempt to print to stderr, after the object dump. */ +#ifdef NDEBUG + /* No debugging: compile away the assertions: */ +# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ + ((void)0) +#else + /* With debugging: generate checks: */ +# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ + ((expr) \ + ? (void)(0) \ + : _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \ + (msg), (filename), (lineno), (func))) +#endif + +#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ + _PyObject_ASSERT_FROM((obj), expr, (msg), __FILE__, __LINE__, __func__) +#define _PyObject_ASSERT(obj, expr) \ + _PyObject_ASSERT_WITH_MSG((obj), expr, NULL) + +#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ + _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) + +/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined, + to avoid causing compiler/linker errors when building extensions without + NDEBUG against a Python built with NDEBUG defined. + + msg, expr and function can be NULL. */ +PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed( + PyObject *obj, + const char *expr, + const char *msg, + const char *file, + int line, + const char *function); + +/* Check if an object is consistent. For example, ensure that the reference + counter is greater than or equal to 1, and ensure that ob_type is not NULL. + + Call _PyObject_AssertFailed() if the object is inconsistent. + + If check_content is zero, only check header fields: reduce the overhead. + + The function always return 1. The return value is just here to be able to + write: + + assert(_PyObject_CheckConsistency(obj, 1)); */ +PyAPI_FUNC(int) _PyObject_CheckConsistency( + PyObject *op, + int check_content); + + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack overflows, +especially in threads (which typically have less stack space to work with). + +A container object can avoid this by bracketing the body of its tp_dealloc +function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_BEGIN(p, mytype_dealloc) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_END // there should be no code after this +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces, +with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL. + +Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base +class, we need to ensure that the trashcan is only triggered on the tp_dealloc +of the actual class being deallocated. Otherwise we might end up with a +partially-deallocated object. To check this, the tp_dealloc function must be +passed as second argument to Py_TRASHCAN_BEGIN(). +*/ + +/* Python 3.9 private API, invoked by the macros below. */ +PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op); +PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate); +/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ +PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); + +#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \ + do { \ + PyThreadState *_tstate = NULL; \ + /* If "cond" is false, then _tstate remains NULL and the deallocator \ + * is run normally without involving the trashcan */ \ + if (cond) { \ + _tstate = _PyThreadState_UncheckedGet(); \ + if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ + break; \ + } \ + } + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_END \ + if (_tstate) { \ + _PyTrash_end(_tstate); \ + } \ + } while (0); + +#define Py_TRASHCAN_BEGIN(op, dealloc) \ + Py_TRASHCAN_BEGIN_CONDITION((op), \ + _PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc))) + +/* The following two macros, Py_TRASHCAN_SAFE_BEGIN and + * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and + * will be removed in the future. + * Use Py_TRASHCAN_BEGIN and Py_TRASHCAN_END instead. + */ +Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro; +#define Py_TRASHCAN_SAFE_BEGIN(op) \ + do { \ + UsingDeprecatedTrashcanMacro cond=1; \ + Py_TRASHCAN_BEGIN_CONDITION((op), cond); +#define Py_TRASHCAN_SAFE_END(op) \ + Py_TRASHCAN_END; \ + } while(0); + +PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj); + +PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); +PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj); + +#define TYPE_MAX_WATCHERS 8 + +typedef int(*PyType_WatchCallback)(PyTypeObject *); +PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback); +PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id); +PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type); +PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); + +/* Attempt to assign a version tag to the given type. + * + * Returns 1 if the type already had a valid version tag or a new one was + * assigned, or 0 if a new tag could not be assigned. + */ +PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type); diff --git a/contrib/tools/python3/Include/cpython/objimpl.h b/contrib/tools/python3/Include/cpython/objimpl.h new file mode 100644 index 0000000000..5a8cdd57c7 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/objimpl.h @@ -0,0 +1,95 @@ +#ifndef Py_CPYTHON_OBJIMPL_H +# error "this header file must not be included directly" +#endif + +static inline size_t _PyObject_SIZE(PyTypeObject *type) { + return _Py_STATIC_CAST(size_t, type->tp_basicsize); +} + +/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a + vrbl-size object with nitems items, exclusive of gc overhead (if any). The + value is rounded up to the closest multiple of sizeof(void *), in order to + ensure that pointer fields at the end of the object are correctly aligned + for the platform (this is of special importance for subclasses of, e.g., + str or int, so that pointers can be stored after the embedded data). + + Note that there's no memory wastage in doing this, as malloc has to + return (at worst) pointer-aligned memory anyway. +*/ +#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 +# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" +#endif + +static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) { + size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize); + size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize); + return _Py_SIZE_ROUND_UP(size, SIZEOF_VOID_P); +} + + +/* This example code implements an object constructor with a custom + allocator, where PyObject_New is inlined, and shows the important + distinction between two steps (at least): + 1) the actual allocation of the object storage; + 2) the initialization of the Python specific fields + in this storage with PyObject_{Init, InitVar}. + + PyObject * + YourObject_New(...) + { + PyObject *op; + + op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); + if (op == NULL) { + return PyErr_NoMemory(); + } + + PyObject_Init(op, &YourTypeStruct); + + op->ob_field = value; + ... + return op; + } + + Note that in C++, the use of the new operator usually implies that + the 1st step is performed automatically for you, so in a C++ class + constructor you would start directly with PyObject_Init/InitVar. */ + + +typedef struct { + /* user context passed as the first argument to the 2 functions */ + void *ctx; + + /* allocate an arena of size bytes */ + void* (*alloc) (void *ctx, size_t size); + + /* free an arena */ + void (*free) (void *ctx, void *ptr, size_t size); +} PyObjectArenaAllocator; + +/* Get the arena allocator. */ +PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); + +/* Set the arena allocator. */ +PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); + + +/* Test if an object implements the garbage collector protocol */ +PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); + + +/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which + defines a different _PyGC_FINALIZED() macro. */ +#ifndef Py_BUILD_CORE + // Kept for backward compatibility with Python 3.8 +# define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) +#endif + + +// Test if a type supports weak references +PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); + +PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); + +PyAPI_FUNC(PyObject *) PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *, + size_t); diff --git a/contrib/tools/python3/Include/cpython/odictobject.h b/contrib/tools/python3/Include/cpython/odictobject.h new file mode 100644 index 0000000000..3822d55486 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/odictobject.h @@ -0,0 +1,43 @@ +#ifndef Py_ODICTOBJECT_H +#define Py_ODICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* OrderedDict */ +/* This API is optional and mostly redundant. */ + +#ifndef Py_LIMITED_API + +typedef struct _odictobject PyODictObject; + +PyAPI_DATA(PyTypeObject) PyODict_Type; +PyAPI_DATA(PyTypeObject) PyODictIter_Type; +PyAPI_DATA(PyTypeObject) PyODictKeys_Type; +PyAPI_DATA(PyTypeObject) PyODictItems_Type; +PyAPI_DATA(PyTypeObject) PyODictValues_Type; + +#define PyODict_Check(op) PyObject_TypeCheck((op), &PyODict_Type) +#define PyODict_CheckExact(op) Py_IS_TYPE((op), &PyODict_Type) +#define PyODict_SIZE(op) PyDict_GET_SIZE((op)) + +PyAPI_FUNC(PyObject *) PyODict_New(void); +PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); + +/* wrappers around PyDict* functions */ +#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), (key)) +#define PyODict_GetItemWithError(od, key) \ + PyDict_GetItemWithError(_PyObject_CAST(od), (key)) +#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), (key)) +#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) +#define PyODict_GetItemString(od, key) \ + PyDict_GetItemString(_PyObject_CAST(od), (key)) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ODICTOBJECT_H */ diff --git a/contrib/tools/python3/Include/cpython/picklebufobject.h b/contrib/tools/python3/Include/cpython/picklebufobject.h new file mode 100644 index 0000000000..f3cbaeef91 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/picklebufobject.h @@ -0,0 +1,31 @@ +/* PickleBuffer object. This is built-in for ease of use from third-party + * C extensions. + */ + +#ifndef Py_PICKLEBUFOBJECT_H +#define Py_PICKLEBUFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; + +#define PyPickleBuffer_Check(op) Py_IS_TYPE((op), &PyPickleBuffer_Type) + +/* Create a PickleBuffer redirecting to the given buffer-enabled object */ +PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); +/* Get the PickleBuffer's underlying view to the original object + * (NULL if released) + */ +PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); +/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ +PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/contrib/tools/python3/Include/cpython/pthread_stubs.h b/contrib/tools/python3/Include/cpython/pthread_stubs.h new file mode 100644 index 0000000000..83f0b08693 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pthread_stubs.h @@ -0,0 +1,88 @@ +#ifndef Py_CPYTHON_PTRHEAD_STUBS_H +#define Py_CPYTHON_PTRHEAD_STUBS_H + +#if !defined(HAVE_PTHREAD_STUBS) +# error "this header file requires stubbed pthreads." +#endif + +#ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +#endif + +/* Minimal pthread stubs for CPython. + * + * The stubs implement the minimum pthread API for CPython. + * - pthread_create() fails. + * - pthread_exit() calls exit(0). + * - pthread_key_*() functions implement minimal TSS without destructor. + * - all other functions do nothing and return 0. + */ + +#ifdef __wasi__ +// WASI's bits/alltypes.h provides type definitions when __NEED_ is set. +// The header file can be included multiple times. +# define __NEED_pthread_cond_t 1 +# define __NEED_pthread_condattr_t 1 +# define __NEED_pthread_mutex_t 1 +# define __NEED_pthread_mutexattr_t 1 +# define __NEED_pthread_key_t 1 +# define __NEED_pthread_t 1 +# define __NEED_pthread_attr_t 1 +# error #include <bits/alltypes.h> +#else +typedef struct { void *__x; } pthread_cond_t; +typedef struct { unsigned __attr; } pthread_condattr_t; +typedef struct { void *__x; } pthread_mutex_t; +typedef struct { unsigned __attr; } pthread_mutexattr_t; +typedef unsigned pthread_key_t; +typedef unsigned pthread_t; +typedef struct { unsigned __attr; } pthread_attr_t; +#endif + +// mutex +PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex, + const pthread_mutexattr_t *restrict attr); +PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex); + +// condition +PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond, + const pthread_condattr_t *restrict attr); +PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex); +PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); +PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr); +PyAPI_FUNC(int) pthread_condattr_setclock( + pthread_condattr_t *attr, clockid_t clock_id); + +// pthread +PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void *), + void *restrict arg); +PyAPI_FUNC(int) pthread_detach(pthread_t thread); +PyAPI_FUNC(pthread_t) pthread_self(void); +PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); +PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); +PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr); + + +// pthread_key +#ifndef PTHREAD_KEYS_MAX +# define PTHREAD_KEYS_MAX 128 +#endif + +PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key, + void (*destr_function)(void *)); +PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key); +PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key); +PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value); + +#endif // Py_CPYTHON_PTRHEAD_STUBS_H diff --git a/contrib/tools/python3/Include/cpython/pyctype.h b/contrib/tools/python3/Include/cpython/pyctype.h new file mode 100644 index 0000000000..729d93275e --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pyctype.h @@ -0,0 +1,39 @@ +#ifndef Py_LIMITED_API +#ifndef PYCTYPE_H +#define PYCTYPE_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; + +/* Unlike their C counterparts, the following macros are not meant to + * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument + * must be a signed/unsigned char. */ +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; +PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#ifdef __cplusplus +} +#endif +#endif /* !PYCTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/pydebug.h b/contrib/tools/python3/Include/cpython/pydebug.h new file mode 100644 index 0000000000..f6ebd99ed7 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pydebug.h @@ -0,0 +1,38 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DebugFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_VerboseFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_QuietFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InteractiveFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InspectFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_OptimizeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_BytesWarningFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_FrozenFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoUserSiteDirectory; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UnbufferedStdioFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HashRandomizationFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IsolatedFlag; + +#ifdef MS_WINDOWS +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +#endif + +/* this is a wrapper around getenv() that pays attention to + Py_IgnoreEnvironmentFlag. It should be used for getting variables like + PYTHONPATH and PYTHONHOME from the environment */ +PyAPI_FUNC(char*) Py_GETENV(const char *name); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/pyerrors.h b/contrib/tools/python3/Include/cpython/pyerrors.h new file mode 100644 index 0000000000..156665cbdb --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pyerrors.h @@ -0,0 +1,178 @@ +#ifndef Py_CPYTHON_ERRORS_H +# error "this header file must not be included directly" +#endif + +/* Error objects */ + +/* PyException_HEAD defines the initial segment of every exception class. */ +#define PyException_HEAD PyObject_HEAD PyObject *dict;\ + PyObject *args; PyObject *notes; PyObject *traceback;\ + PyObject *context; PyObject *cause;\ + char suppress_context; + +typedef struct { + PyException_HEAD +} PyBaseExceptionObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *excs; +} PyBaseExceptionGroupObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *filename; + PyObject *lineno; + PyObject *offset; + PyObject *end_lineno; + PyObject *end_offset; + PyObject *text; + PyObject *print_file_and_line; +} PySyntaxErrorObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *name; + PyObject *path; + PyObject *name_from; +} PyImportErrorObject; + +typedef struct { + PyException_HEAD + PyObject *encoding; + PyObject *object; + Py_ssize_t start; + Py_ssize_t end; + PyObject *reason; +} PyUnicodeErrorObject; + +typedef struct { + PyException_HEAD + PyObject *code; +} PySystemExitObject; + +typedef struct { + PyException_HEAD + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; + PyObject *filename2; +#ifdef MS_WINDOWS + PyObject *winerror; +#endif + Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */ +} PyOSErrorObject; + +typedef struct { + PyException_HEAD + PyObject *value; +} PyStopIterationObject; + +typedef struct { + PyException_HEAD + PyObject *name; +} PyNameErrorObject; + +typedef struct { + PyException_HEAD + PyObject *obj; + PyObject *name; +} PyAttributeErrorObject; + +/* Compatibility typedefs */ +typedef PyOSErrorObject PyEnvironmentErrorObject; +#ifdef MS_WINDOWS +typedef PyOSErrorObject PyWindowsErrorObject; +#endif + +/* Error handling definitions */ + +PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); +PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate); +PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *); +PyAPI_FUNC(void) _PyErr_SetHandledException(PyThreadState *, PyObject *); +PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **); + +/* Context manipulation (PEP 3134) */ + +Py_DEPRECATED(3.12) PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *); + +/* Like PyErr_Format(), but saves current exception as __context__ and + __cause__. + */ +PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( + PyObject *exception, + const char *format, /* ASCII-encoded string */ + ... + ); + +/* In exceptions.c */ + +PyAPI_FUNC(int) _PyException_AddNote( + PyObject *exc, + PyObject *note); + +PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar( + PyObject *orig, + PyObject *excs); + +/* In signalmodule.c */ + +int PySignal_SetWakeupFd(int fd); +PyAPI_FUNC(int) _PyErr_CheckSignals(void); + +/* Support for adding program text to SyntaxErrors */ + +PyAPI_FUNC(void) PyErr_SyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset); + +PyAPI_FUNC(void) PyErr_RangedSyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset, + int end_lineno, + int end_col_offset); + +PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( + PyObject *filename, + int lineno); + +PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject( + PyObject *filename, + int lineno, + const char* encoding); + +PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( + PyObject *object, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); + +PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( + const char *err_msg, + PyObject *obj); + +PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc( + const char *func, + const char *message); + +PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( + const char *func, + const char *format, + ...); + +extern PyObject *_PyErr_SetImportErrorWithNameFrom( + PyObject *, + PyObject *, + PyObject *, + PyObject *); + + +#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message)) diff --git a/contrib/tools/python3/Include/cpython/pyfpe.h b/contrib/tools/python3/Include/cpython/pyfpe.h new file mode 100644 index 0000000000..cc2def63aa --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pyfpe.h @@ -0,0 +1,15 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H +/* Header excluded from the stable API */ +#ifndef Py_LIMITED_API + +/* These macros used to do something when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them though, + * to avoid breaking API users. + */ + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif /* !defined(Py_LIMITED_API) */ +#endif /* !Py_PYFPE_H */ diff --git a/contrib/tools/python3/Include/cpython/pyframe.h b/contrib/tools/python3/Include/cpython/pyframe.h new file mode 100644 index 0000000000..0e2afff925 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pyframe.h @@ -0,0 +1,35 @@ +#ifndef Py_CPYTHON_PYFRAME_H +# error "this header file must not be included directly" +#endif + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) Py_IS_TYPE((op), &PyFrame_Type) + +PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); +PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame); +PyAPI_FUNC(PyObject*) PyFrame_GetVar(PyFrameObject *frame, PyObject *name); +PyAPI_FUNC(PyObject*) PyFrame_GetVarString(PyFrameObject *frame, const char *name); + +/* The following functions are for use by debuggers and other tools + * implementing custom frame evaluators with PEP 523. */ + +struct _PyInterpreterFrame; + +/* Returns the code object of the frame (strong reference). + * Does not raise an exception. */ +PyAPI_FUNC(PyObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame); + +/* Returns a byte ofsset into the last executed instruction. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame); + +/* Returns the currently executing line number, or -1 if there is no line number. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame); diff --git a/contrib/tools/python3/Include/cpython/pylifecycle.h b/contrib/tools/python3/Include/cpython/pylifecycle.h new file mode 100644 index 0000000000..4daea33bf8 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pylifecycle.h @@ -0,0 +1,111 @@ +#ifndef Py_CPYTHON_PYLIFECYCLE_H +# error "this header file must not be included directly" +#endif + +/* Py_FrozenMain is kept out of the Limited API until documented and present + in all builds of Python */ +PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv); + +/* Only used by applications that embed the interpreter and need to + * override the standard encoding determination mechanism + */ +Py_DEPRECATED(3.11) PyAPI_FUNC(int) Py_SetStandardStreamEncoding( + const char *encoding, + const char *errors); + +/* PEP 432 Multi-phase initialization API (Private while provisional!) */ + +PyAPI_FUNC(PyStatus) Py_PreInitialize( + const PyPreConfig *src_config); +PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs( + const PyPreConfig *src_config, + Py_ssize_t argc, + char **argv); +PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( + const PyPreConfig *src_config, + Py_ssize_t argc, + wchar_t **argv); + +PyAPI_FUNC(int) _Py_IsCoreInitialized(void); + + +/* Initialization and finalization */ + +PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( + const PyConfig *config); +PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); + +PyAPI_FUNC(int) Py_RunMain(void); + + +PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +PyAPI_FUNC(void) _Py_RestoreSignals(void); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename); + +Py_DEPRECATED(3.11) PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *); + +PyAPI_FUNC(const char *) _Py_gitidentifier(void); +PyAPI_FUNC(const char *) _Py_gitversion(void); + +PyAPI_FUNC(int) _Py_IsFinalizing(void); +PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp); + +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); +PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); + +/* Legacy locale support */ +PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); +PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); +PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); + +/* --- PyInterpreterConfig ------------------------------------ */ + +#define PyInterpreterConfig_DEFAULT_GIL (0) +#define PyInterpreterConfig_SHARED_GIL (1) +#define PyInterpreterConfig_OWN_GIL (2) + +typedef struct { + // XXX "allow_object_sharing"? "own_objects"? + int use_main_obmalloc; + int allow_fork; + int allow_exec; + int allow_threads; + int allow_daemon_threads; + int check_multi_interp_extensions; + int gil; +} PyInterpreterConfig; + +#define _PyInterpreterConfig_INIT \ + { \ + .use_main_obmalloc = 0, \ + .allow_fork = 0, \ + .allow_exec = 0, \ + .allow_threads = 1, \ + .allow_daemon_threads = 0, \ + .check_multi_interp_extensions = 1, \ + .gil = PyInterpreterConfig_OWN_GIL, \ + } + +#define _PyInterpreterConfig_LEGACY_INIT \ + { \ + .use_main_obmalloc = 1, \ + .allow_fork = 1, \ + .allow_exec = 1, \ + .allow_threads = 1, \ + .allow_daemon_threads = 1, \ + .check_multi_interp_extensions = 0, \ + .gil = PyInterpreterConfig_SHARED_GIL, \ + } + +PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig( + PyThreadState **tstate_p, + const PyInterpreterConfig *config); + +typedef void (*atexit_datacallbackfunc)(void *); +PyAPI_FUNC(int) _Py_AtExit( + PyInterpreterState *, atexit_datacallbackfunc, void *); diff --git a/contrib/tools/python3/Include/cpython/pymem.h b/contrib/tools/python3/Include/cpython/pymem.h new file mode 100644 index 0000000000..d1054d7652 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pymem.h @@ -0,0 +1,98 @@ +#ifndef Py_CPYTHON_PYMEM_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); +PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); + +/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ +PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); + +/* strdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); + +/* strdup() using PyMem_Malloc() */ +PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); + +/* wcsdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); + + +typedef enum { + /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ + PYMEM_DOMAIN_RAW, + + /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ + PYMEM_DOMAIN_MEM, + + /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ + PYMEM_DOMAIN_OBJ +} PyMemAllocatorDomain; + +typedef enum { + PYMEM_ALLOCATOR_NOT_SET = 0, + PYMEM_ALLOCATOR_DEFAULT = 1, + PYMEM_ALLOCATOR_DEBUG = 2, + PYMEM_ALLOCATOR_MALLOC = 3, + PYMEM_ALLOCATOR_MALLOC_DEBUG = 4, +#ifdef WITH_PYMALLOC + PYMEM_ALLOCATOR_PYMALLOC = 5, + PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6, +#endif +} PyMemAllocatorName; + + +typedef struct { + /* user context passed as the first argument to the 4 functions */ + void *ctx; + + /* allocate a memory block */ + void* (*malloc) (void *ctx, size_t size); + + /* allocate a memory block initialized by zeros */ + void* (*calloc) (void *ctx, size_t nelem, size_t elsize); + + /* allocate or resize a memory block */ + void* (*realloc) (void *ctx, void *ptr, size_t new_size); + + /* release a memory block */ + void (*free) (void *ctx, void *ptr); +} PyMemAllocatorEx; + +/* Get the memory block allocator of the specified domain. */ +PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Set the memory block allocator of the specified domain. + + The new allocator must return a distinct non-NULL pointer when requesting + zero bytes. + + For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL + is not held when the allocator is called. + + If the new allocator is not a hook (don't call the previous allocator), the + PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks + on top on the new allocator. */ +PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Setup hooks to detect bugs in the following Python memory allocator + functions: + + - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() + - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() + - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() + + Newly allocated memory is filled with the byte 0xCB, freed memory is filled + with the byte 0xDB. Additional checks: + + - detect API violations, ex: PyObject_Free() called on a buffer allocated + by PyMem_Malloc() + - detect write before the start of the buffer (buffer underflow) + - detect write after the end of the buffer (buffer overflow) + + The function does nothing if Python is not compiled is debug mode. */ +PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); diff --git a/contrib/tools/python3/Include/cpython/pystate.h b/contrib/tools/python3/Include/cpython/pystate.h new file mode 100644 index 0000000000..628f2e0996 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pystate.h @@ -0,0 +1,444 @@ +#ifndef Py_CPYTHON_PYSTATE_H +# error "this header file must not be included directly" +#endif + + +/* +Runtime Feature Flags + +Each flag indicate whether or not a specific runtime feature +is available in a given context. For example, forking the process +might not be allowed in the current interpreter (i.e. os.fork() would fail). +*/ + +/* Set if the interpreter share obmalloc runtime state + with the main interpreter. */ +#define Py_RTFLAGS_USE_MAIN_OBMALLOC (1UL << 5) + +/* Set if import should check a module for subinterpreter support. */ +#define Py_RTFLAGS_MULTI_INTERP_EXTENSIONS (1UL << 8) + +/* Set if threads are allowed. */ +#define Py_RTFLAGS_THREADS (1UL << 10) + +/* Set if daemon threads are allowed. */ +#define Py_RTFLAGS_DAEMON_THREADS (1UL << 11) + +/* Set if os.fork() is allowed. */ +#define Py_RTFLAGS_FORK (1UL << 15) + +/* Set if os.exec*() is allowed. */ +#define Py_RTFLAGS_EXEC (1UL << 16) + + +PyAPI_FUNC(int) _PyInterpreterState_HasFeature(PyInterpreterState *interp, + unsigned long feature); + + +/* private interpreter helpers */ + +PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); + +PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); + + +/* State unique per thread */ + +/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ +typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); + +/* The following values are used for 'what' for tracefunc functions + * + * To add a new kind of trace event, also update "trace_init" in + * Python/sysmodule.c to define the Python level event name + */ +#define PyTrace_CALL 0 +#define PyTrace_EXCEPTION 1 +#define PyTrace_LINE 2 +#define PyTrace_RETURN 3 +#define PyTrace_C_CALL 4 +#define PyTrace_C_EXCEPTION 5 +#define PyTrace_C_RETURN 6 +#define PyTrace_OPCODE 7 + +// Internal structure: you should not use it directly, but use public functions +// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). +typedef struct _PyCFrame { + /* This struct will be threaded through the C stack + * allowing fast access to per-thread state that needs + * to be accessed quickly by the interpreter, but can + * be modified outside of the interpreter. + * + * WARNING: This makes data on the C stack accessible from + * heap objects. Care must be taken to maintain stack + * discipline and make sure that instances of this struct cannot + * accessed outside of their lifetime. + */ + /* Pointer to the currently executing frame (it can be NULL) */ + struct _PyInterpreterFrame *current_frame; + struct _PyCFrame *previous; +} _PyCFrame; + +typedef struct _err_stackitem { + /* This struct represents a single execution context where we might + * be currently handling an exception. It is a per-coroutine state + * (coroutine in the computer science sense, including the thread + * and generators). + * + * This is used as an entry on the exception stack, where each + * entry indicates if it is currently handling an exception. + * This ensures that the exception state is not impacted + * by "yields" from an except handler. The thread + * always has an entry (the bottom-most one). + */ + + /* The exception currently being handled in this context, if any. */ + PyObject *exc_value; + + struct _err_stackitem *previous_item; + +} _PyErr_StackItem; + +typedef struct _stack_chunk { + struct _stack_chunk *previous; + size_t size; + size_t top; + PyObject * data[1]; /* Variable sized */ +} _PyStackChunk; + +struct _py_trashcan { + int delete_nesting; + PyObject *delete_later; +}; + +struct _ts { + /* See Python/ceval.c for comments explaining most fields */ + + PyThreadState *prev; + PyThreadState *next; + PyInterpreterState *interp; + + struct { + /* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ + unsigned int initialized:1; + + /* Has been bound to an OS thread. */ + unsigned int bound:1; + /* Has been unbound from its OS thread. */ + unsigned int unbound:1; + /* Has been bound aa current for the GILState API. */ + unsigned int bound_gilstate:1; + /* Currently in use (maybe holds the GIL). */ + unsigned int active:1; + + /* various stages of finalization */ + unsigned int finalizing:1; + unsigned int cleared:1; + unsigned int finalized:1; + + /* padding to align to 4 bytes */ + unsigned int :24; + } _status; + + int py_recursion_remaining; + int py_recursion_limit; + + int c_recursion_remaining; + int recursion_headroom; /* Allow 50 more calls to handle any errors. */ + + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + int what_event; /* The event currently being monitored, if any. */ + + /* Pointer to current _PyCFrame in the C stack frame of the currently, + * or most recently, executing _PyEval_EvalFrameDefault. */ + _PyCFrame *cframe; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + /* The exception currently being raised */ + PyObject *current_exception; + + /* Pointer to the top of the exception stack for the exceptions + * we may be currently handling. (See _PyErr_StackItem above.) + * This is never NULL. */ + _PyErr_StackItem *exc_info; + + PyObject *dict; /* Stores per-thread state */ + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + unsigned long thread_id; /* Thread id where this tstate was created */ + + /* Native thread id where this tstate was created. This will be 0 except on + * those platforms that have the notion of native thread id, for which the + * macro PY_HAVE_THREAD_NATIVE_ID is then defined. + */ + unsigned long native_thread_id; + + struct _py_trashcan trash; + + /* Called when a thread state is deleted normally, but not when it + * is destroyed after fork(). + * Pain: to prevent rare but fatal shutdown errors (issue 18808), + * Thread.join() must wait for the join'ed thread's tstate to be unlinked + * from the tstate chain. That happens at the end of a thread's life, + * in pystate.c. + * The obvious way doesn't quite work: create a lock which the tstate + * unlinking code releases, and have Thread.join() wait to acquire that + * lock. The problem is that we _are_ at the end of the thread's life: + * if the thread holds the last reference to the lock, decref'ing the + * lock will delete the lock, and that may trigger arbitrary Python code + * if there's a weakref, with a callback, to the lock. But by this time + * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest + * of C code can be allowed to run (in particular it must not be possible to + * release the GIL). + * So instead of holding the lock directly, the tstate holds a weakref to + * the lock: that's the value of on_delete_data below. Decref'ing a + * weakref is harmless. + * on_delete points to _threadmodule.c's static release_sentinel() function. + * After the tstate is unlinked, release_sentinel is called with the + * weakref-to-lock (on_delete_data) argument, and release_sentinel releases + * the indirectly held lock. + */ + void (*on_delete)(void *); + void *on_delete_data; + + int coroutine_origin_tracking_depth; + + PyObject *async_gen_firstiter; + PyObject *async_gen_finalizer; + + PyObject *context; + uint64_t context_ver; + + /* Unique thread state id. */ + uint64_t id; + + _PyStackChunk *datastack_chunk; + PyObject **datastack_top; + PyObject **datastack_limit; + /* XXX signal handlers should also be here */ + + /* The following fields are here to avoid allocation during init. + The data is exposed through PyThreadState pointer fields. + These fields should not be accessed directly outside of init. + This is indicated by an underscore prefix on the field names. + + All other PyInterpreterState pointer fields are populated when + needed and default to NULL. + */ + // Note some fields do not have a leading underscore for backward + // compatibility. See https://bugs.python.org/issue45953#msg412046. + + /* The thread's exception stack entry. (Always the last entry.) */ + _PyErr_StackItem exc_state; + + /* The bottom-most frame on the stack. */ + _PyCFrame root_cframe; +}; + +/* WASI has limited call stack. Python's recursion limit depends on code + layout, optimization, and WASI runtime. Wasmtime can handle about 700 + recursions, sometimes less. 500 is a more conservative limit. */ +#ifndef C_RECURSION_LIMIT +# ifdef __wasi__ +# define C_RECURSION_LIMIT 500 +# else + // This value is duplicated in Lib/test/support/__init__.py +# define C_RECURSION_LIMIT 1500 +# endif +#endif + +/* other API */ + +// Alias for backward compatibility with Python 3.8 +#define _PyInterpreterState_Get PyInterpreterState_Get + +/* An alias for the internal _PyThreadState_New(), + kept for stable ABI compatibility. */ +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); + +/* Similar to PyThreadState_Get(), but don't issue a fatal error + * if it is NULL. */ +PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); + +PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate); + +// Disable tracing and profiling. +PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); + +// Reset tracing and profiling: enable them if a trace function or a profile +// function is set, otherwise disable them. +PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate); + +/* PyGILState */ + +/* Helper/diagnostic function - return 1 if the current thread + currently holds the GIL, 0 otherwise. + + The function returns 1 if _PyGILState_check_enabled is non-zero. */ +PyAPI_FUNC(int) PyGILState_Check(void); + +/* Get the single PyInterpreterState used by this process' GILState + implementation. + + This function doesn't check for error. Return NULL before _PyGILState_Init() + is called and after _PyGILState_Fini() is called. + + See also _PyInterpreterState_Get() and _PyInterpreterState_GET(). */ +PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); + +/* The implementation of sys._current_exceptions() Returns a dict mapping + thread id to that thread's current exception. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void); + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); + +/* Frame evaluation API */ + +typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int); + +PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc( + PyInterpreterState *interp); +PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc( + PyInterpreterState *interp, + _PyFrameEvalFunction eval_frame); + +PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp); + +/* Get a copy of the current interpreter configuration. + + Return 0 on success. Raise an exception and return -1 on error. + + The caller must initialize 'config', using PyConfig_InitPythonConfig() + for example. + + Python must be preinitialized to call this method. + The caller must hold the GIL. + + Once done with the configuration, PyConfig_Clear() must be called to clear + it. */ +PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( + struct PyConfig *config); + +/* Set the configuration of the current interpreter. + + This function should be called during or just after the Python + initialization. + + Update the sys module with the new configuration. If the sys module was + modified directly after the Python initialization, these changes are lost. + + Some configuration like faulthandler or warnoptions can be updated in the + configuration, but don't reconfigure Python (don't enable/disable + faulthandler and don't reconfigure warnings filters). + + Return 0 on success. Raise an exception and return -1 on error. + + The configuration should come from _PyInterpreterState_GetConfigCopy(). */ +PyAPI_FUNC(int) _PyInterpreterState_SetConfig( + const struct PyConfig *config); + +// Get the configuration of the current interpreter. +// The caller must hold the GIL. +PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); + + +/* cross-interpreter data */ + +// _PyCrossInterpreterData is similar to Py_buffer as an effectively +// opaque struct that holds data outside the object machinery. This +// is necessary to pass safely between interpreters in the same process. +typedef struct _xid _PyCrossInterpreterData; + +typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); +typedef void (*xid_freefunc)(void *); + +struct _xid { + // data is the cross-interpreter-safe derivation of a Python object + // (see _PyObject_GetCrossInterpreterData). It will be NULL if the + // new_object func (below) encodes the data. + void *data; + // obj is the Python object from which the data was derived. This + // is non-NULL only if the data remains bound to the object in some + // way, such that the object must be "released" (via a decref) when + // the data is released. In that case the code that sets the field, + // likely a registered "crossinterpdatafunc", is responsible for + // ensuring it owns the reference (i.e. incref). + PyObject *obj; + // interp is the ID of the owning interpreter of the original + // object. It corresponds to the active interpreter when + // _PyObject_GetCrossInterpreterData() was called. This should only + // be set by the cross-interpreter machinery. + // + // We use the ID rather than the PyInterpreterState to avoid issues + // with deleted interpreters. Note that IDs are never re-used, so + // each one will always correspond to a specific interpreter + // (whether still alive or not). + int64_t interp; + // new_object is a function that returns a new object in the current + // interpreter given the data. The resulting object (a new + // reference) will be equivalent to the original object. This field + // is required. + xid_newobjectfunc new_object; + // free is called when the data is released. If it is NULL then + // nothing will be done to free the data. For some types this is + // okay (e.g. bytes) and for those types this field should be set + // to NULL. However, for most the data was allocated just for + // cross-interpreter use, so it must be freed when + // _PyCrossInterpreterData_Release is called or the memory will + // leak. In that case, at the very least this field should be set + // to PyMem_RawFree (the default if not explicitly set to NULL). + // The call will happen with the original interpreter activated. + xid_freefunc free; +}; + +PyAPI_FUNC(void) _PyCrossInterpreterData_Init( + _PyCrossInterpreterData *data, + PyInterpreterState *interp, void *shared, PyObject *obj, + xid_newobjectfunc new_object); +PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( + _PyCrossInterpreterData *, + PyInterpreterState *interp, const size_t, PyObject *, + xid_newobjectfunc); +PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( + PyInterpreterState *, _PyCrossInterpreterData *); + +PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); +PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); +PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); + +PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); + +/* cross-interpreter data registry */ + +typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *, + _PyCrossInterpreterData *); + +PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *); +PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); diff --git a/contrib/tools/python3/Include/cpython/pythonrun.h b/contrib/tools/python3/Include/cpython/pythonrun.h new file mode 100644 index 0000000000..fb61765537 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pythonrun.h @@ -0,0 +1,121 @@ +#ifndef Py_CPYTHON_PYTHONRUN_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) _PyRun_SimpleFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_AnyFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) _PyRun_AnyFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) _PyRun_InteractiveLoopObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); + + +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyObject *globals, + PyObject *locals, + int closeit, + PyCompilerFlags *flags); + + +PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + int optimize); +PyAPI_FUNC(PyObject *) Py_CompileStringObject( + const char *str, + PyObject *filename, int start, + PyCompilerFlags *flags, + int optimize); + +#define Py_CompileString(str, p, s) Py_CompileStringExFlags((str), (p), (s), NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags((str), (p), (s), (f), -1) + + +PyAPI_FUNC(const char *) _Py_SourceAsString( + PyObject *cmd, + const char *funcname, + const char *what, + PyCompilerFlags *cf, + PyObject **cmd_copy); + + +/* A function flavor is also exported by libpython. It is required when + libpython is accessed directly rather than using header files which defines + macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to + export functions in pythonXX.dll. */ +PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name); +PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit); +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleString(const char *s); +PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c); +PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p); +PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c); +PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags); + +/* Use macros for a bunch of old variants */ +#define PyRun_String(str, s, g, l) PyRun_StringFlags((str), (s), (g), (l), NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags((fp), (name), 0, NULL) +#define PyRun_AnyFileEx(fp, name, closeit) \ + PyRun_AnyFileExFlags((fp), (name), (closeit), NULL) +#define PyRun_AnyFileFlags(fp, name, flags) \ + PyRun_AnyFileExFlags((fp), (name), 0, (flags)) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags((s), NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags((f), (p), 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags((f), (p), (c), NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags((f), (p), NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags((f), (p), NULL) +#define PyRun_File(fp, p, s, g, l) \ + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, NULL) +#define PyRun_FileEx(fp, p, s, g, l, c) \ + PyRun_FileExFlags((fp), (p), (s), (g), (l), (c), NULL) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, (flags)) + + +/* Stuff with no proper home (yet) */ +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); diff --git a/contrib/tools/python3/Include/cpython/pythread.h b/contrib/tools/python3/Include/cpython/pythread.h new file mode 100644 index 0000000000..449b7cc6dd --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pythread.h @@ -0,0 +1,42 @@ +#ifndef Py_CPYTHON_PYTHREAD_H +# error "this header file must not be included directly" +#endif + +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) + +#ifdef HAVE_FORK +/* Private function to reinitialize a lock at fork in the child process. + Reset the lock to the unlocked state. + Return 0 on success, return -1 on error. */ +PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); +#endif /* HAVE_FORK */ + +#ifdef HAVE_PTHREAD_H + /* Darwin needs pthread.h to know type name the pthread_key_t. */ +# include <pthread.h> +# define NATIVE_TSS_KEY_T pthread_key_t +#elif defined(NT_THREADS) + /* In Windows, native TSS key type is DWORD, + but hardcode the unsigned long to avoid errors for include directive. + */ +# define NATIVE_TSS_KEY_T unsigned long +#elif defined(HAVE_PTHREAD_STUBS) +#error # include "cpython/pthread_stubs.h" +# define NATIVE_TSS_KEY_T pthread_key_t +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + +/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is + exposed to allow static allocation in the API clients. Even in this case, + you must handle TSS keys through API functions due to compatibility. +*/ +struct _Py_tss_t { + int _is_initialized; + NATIVE_TSS_KEY_T _key; +}; + +#undef NATIVE_TSS_KEY_T + +/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ +#define Py_tss_NEEDS_INIT {0} diff --git a/contrib/tools/python3/Include/cpython/pytime.h b/contrib/tools/python3/Include/cpython/pytime.h new file mode 100644 index 0000000000..16d88d191e --- /dev/null +++ b/contrib/tools/python3/Include/cpython/pytime.h @@ -0,0 +1,331 @@ +// The _PyTime_t API is written to use timestamp and timeout values stored in +// various formats and to read clocks. +// +// The _PyTime_t type is an integer to support directly common arithmetic +// operations like t1 + t2. +// +// The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type +// is signed to support negative timestamps. The supported range is around +// [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the +// supported date range is around [1677-09-21; 2262-04-11]. +// +// Formats: +// +// * seconds +// * seconds as a floating pointer number (C double) +// * milliseconds (10^-3 seconds) +// * microseconds (10^-6 seconds) +// * 100 nanoseconds (10^-7 seconds) +// * nanoseconds (10^-9 seconds) +// * timeval structure, 1 microsecond resolution (10^-6 seconds) +// * timespec structure, 1 nanosecond resolution (10^-9 seconds) +// +// Integer overflows are detected and raise OverflowError. Conversion to a +// resolution worse than 1 nanosecond is rounded correctly with the requested +// rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling +// (towards +inf), half even and up (away from zero). +// +// Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so +// the caller doesn't have to handle errors and doesn't need to hold the GIL. +// For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on +// overflow. +// +// Clocks: +// +// * System clock +// * Monotonic clock +// * Performance counter +// +// Operations like (t * k / q) with integers are implemented in a way to reduce +// the risk of integer overflow. Such operation is used to convert a clock +// value expressed in ticks with a frequency to _PyTime_t, like +// QueryPerformanceCounter() with QueryPerformanceFrequency(). + +#ifndef Py_LIMITED_API +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __clang__ +struct timeval; +#endif + +/* _PyTime_t: Python timestamp with subsecond precision. It can be used to + store a duration, and so indirectly a date (related to another date, like + UNIX epoch). */ +typedef int64_t _PyTime_t; +// _PyTime_MIN nanoseconds is around -292.3 years +#define _PyTime_MIN INT64_MIN +// _PyTime_MAX nanoseconds is around +292.3 years +#define _PyTime_MAX INT64_MAX +#define _SIZEOF_PYTIME_T 8 + +typedef enum { + /* Round towards minus infinity (-inf). + For example, used to read a clock. */ + _PyTime_ROUND_FLOOR=0, + /* Round towards infinity (+inf). + For example, used for timeout to wait "at least" N seconds. */ + _PyTime_ROUND_CEILING=1, + /* Round to nearest with ties going to nearest even integer. + For example, used to round from a Python float. */ + _PyTime_ROUND_HALF_EVEN=2, + /* Round away from zero + For example, used for timeout. _PyTime_ROUND_CEILING rounds + -1e-9 to 0 milliseconds which causes bpo-31786 issue. + _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps + the timeout sign as expected. select.poll(timeout) must block + for negative values." */ + _PyTime_ROUND_UP=3, + /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be + used for timeouts. */ + _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP +} _PyTime_round_t; + + +/* Convert a time_t to a PyLong. */ +PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( + time_t sec); + +/* Convert a PyLong to a time_t. */ +PyAPI_FUNC(time_t) _PyLong_AsTime_t( + PyObject *obj); + +/* Convert a number of seconds, int or float, to time_t. */ +PyAPI_FUNC(int) _PyTime_ObjectToTime_t( + PyObject *obj, + time_t *sec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timeval structure. + usec is in the range [0; 999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimeval( + PyObject *obj, + time_t *sec, + long *usec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timespec structure. + nsec is in the range [0; 999999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimespec( + PyObject *obj, + time_t *sec, + long *nsec, + _PyTime_round_t); + + +/* Create a timestamp from a number of seconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); + +/* Macro to create a timestamp from a number of seconds, no integer overflow. + Only use the macro for small values, prefer _PyTime_FromSeconds(). */ +#define _PYTIME_FROMSECONDS(seconds) \ + ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) + +/* Create a timestamp from a number of nanoseconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); + +/* Create a timestamp from a number of microseconds. + * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us); + +/* Create a timestamp from nanoseconds (Python int). */ +PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, + PyObject *obj); + +/* Convert a number of seconds (Python float or int) to a timestamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds as a C double. */ +PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); + +/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of microseconds (10^-6 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t); + +#ifdef MS_WINDOWS +// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds). +PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t, + _PyTime_round_t round); +#endif + +/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int + object. */ +PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); + +#ifndef MS_WINDOWS +/* Create a timestamp from a timeval structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); +#endif + +/* Convert a timestamp to a timeval structure (microsecond resolution). + tv_usec is always positive. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow. + On overflow, clamp tv_sec to _PyTime_t min/max. */ +PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds (secs) and microseconds (us). + us is always positive. This function is similar to _PyTime_AsTimeval() + except that secs is always a time_t type, whereas the timeval structure + uses a C long for tv_sec on Windows. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( + _PyTime_t t, + time_t *secs, + int *us, + _PyTime_round_t round); + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) +/* Create a timestamp from a timespec structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); + +/* Convert a timestamp to a timespec structure (nanosecond resolution). + tv_nsec is always positive. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); + +/* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow. + On overflow, clamp tv_sec to _PyTime_t min/max. */ +PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts); +#endif + + +// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2); + +/* Compute ticks * mul / div. + Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. + The caller must ensure that ((div - 1) * mul) cannot overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, + _PyTime_t mul, + _PyTime_t div); + +/* Structure used by time.get_clock_info() */ +typedef struct { + const char *implementation; + int monotonic; + int adjustable; + double resolution; +} _Py_clock_info_t; + +/* Get the current time from the system clock. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and clamp the clock to + [_PyTime_MIN; _PyTime_MAX]. + + Use _PyTime_GetSystemClockWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); + +/* Get the current time from the system clock. + * On success, set *t and *info (if not NULL), and return 0. + * On error, raise an exception and return -1. + */ +PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and clamp the clock to + [_PyTime_MIN; _PyTime_MAX]. + + Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + + +/* Converts a timestamp to the Gregorian time, using the local time zone. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); + +/* Converts a timestamp to the Gregorian time, assuming UTC. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + If the internal clock fails, silently ignore the error and return 0. + On integer overflow, silently ignore the overflow and clamp the clock to + [_PyTime_MIN; _PyTime_MAX]. + + Use _PyTime_GetPerfCounterWithInfo() to check for failure. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + + +// Create a deadline. +// Pseudo code: _PyTime_GetMonotonicClock() + timeout. +PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout); + +// Get remaining time from a deadline. +// Pseudo code: deadline - _PyTime_GetMonotonicClock(). +PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ diff --git a/contrib/tools/python3/Include/cpython/setobject.h b/contrib/tools/python3/Include/cpython/setobject.h new file mode 100644 index 0000000000..20fd63eaae --- /dev/null +++ b/contrib/tools/python3/Include/cpython/setobject.h @@ -0,0 +1,72 @@ +#ifndef Py_CPYTHON_SETOBJECT_H +# error "this header file must not be included directly" +#endif + +/* There are three kinds of entries in the table: + +1. Unused: key == NULL and hash == 0 +2. Dummy: key == dummy and hash == -1 +3. Active: key != NULL and key != dummy and hash != -1 + +The hash field of Unused slots is always zero. + +The hash field of Dummy slots are set to -1 +meaning that dummy entries can be detected by +either entry->key==dummy or by entry->hash==-1. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + PyObject *key; + Py_hash_t hash; /* Cached hash code of the key */ +} setentry; + +/* The SetObject data structure is shared by set and frozenset objects. + +Invariant for sets: + - hash is -1 + +Invariants for frozensets: + - data is immutable. + - hash is the hash of the frozenset or -1 if not computed yet. + +*/ + +typedef struct { + PyObject_HEAD + + Py_ssize_t fill; /* Number active and dummy entries*/ + Py_ssize_t used; /* Number active entries */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. + */ + setentry *table; + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + + setentry smalltable[PySet_MINSIZE]; + PyObject *weakreflist; /* List of weak references */ +} PySetObject; + +#define _PySet_CAST(so) \ + (assert(PyAnySet_Check(so)), _Py_CAST(PySetObject*, so)) + +static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) { + return _PySet_CAST(so)->used; +} +#define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so)) + +PyAPI_DATA(PyObject *) _PySet_Dummy; + +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); diff --git a/contrib/tools/python3/Include/cpython/sysmodule.h b/contrib/tools/python3/Include/cpython/sysmodule.h new file mode 100644 index 0000000000..19d9dddc34 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/sysmodule.h @@ -0,0 +1,16 @@ +#ifndef Py_CPYTHON_SYSMODULE_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate, + PyObject *name); + +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); + +typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); + +PyAPI_FUNC(int) PySys_Audit( + const char *event, + const char *argFormat, + ...); +PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); diff --git a/contrib/tools/python3/Include/cpython/traceback.h b/contrib/tools/python3/Include/cpython/traceback.h new file mode 100644 index 0000000000..a4e087b2b4 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/traceback.h @@ -0,0 +1,16 @@ +#ifndef Py_CPYTHON_TRACEBACK_H +# error "this header file must not be included directly" +#endif + +typedef struct _traceback PyTracebackObject; + +struct _traceback { + PyObject_HEAD + PyTracebackObject *tb_next; + PyFrameObject *tb_frame; + int tb_lasti; + int tb_lineno; +}; + +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **); +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); diff --git a/contrib/tools/python3/Include/cpython/tupleobject.h b/contrib/tools/python3/Include/cpython/tupleobject.h new file mode 100644 index 0000000000..f6a1f076e0 --- /dev/null +++ b/contrib/tools/python3/Include/cpython/tupleobject.h @@ -0,0 +1,39 @@ +#ifndef Py_CPYTHON_TUPLEOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + PyObject_VAR_HEAD + /* ob_item contains space for 'ob_size' elements. + Items must normally not be NULL, except during construction when + the tuple is not yet visible outside the function that builds it. */ + PyObject *ob_item[1]; +} PyTupleObject; + +PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); + +/* Cast argument to PyTupleObject* type. */ +#define _PyTuple_CAST(op) \ + (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op))) + +// Macros and static inline functions, trading safety for speed + +static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) { + PyTupleObject *tuple = _PyTuple_CAST(op); + return Py_SIZE(tuple); +} +#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op)) + +#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)]) + +/* Function *only* to be used to fill in brand new tuples */ +static inline void +PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { + PyTupleObject *tuple = _PyTuple_CAST(op); + tuple->ob_item[index] = value; +} +#define PyTuple_SET_ITEM(op, index, value) \ + PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) + +PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/contrib/tools/python3/Include/cpython/unicodeobject.h b/contrib/tools/python3/Include/cpython/unicodeobject.h new file mode 100644 index 0000000000..f177cd9e2a --- /dev/null +++ b/contrib/tools/python3/Include/cpython/unicodeobject.h @@ -0,0 +1,963 @@ +#ifndef Py_CPYTHON_UNICODEOBJECT_H +# error "this header file must not be included directly" +#endif + +/* Py_UNICODE was the native Unicode storage format (code unit) used by + Python and represents a single Unicode element in the Unicode type. + With PEP 393, Py_UNICODE is deprecated and replaced with a + typedef to wchar_t. */ +#define PY_UNICODE_TYPE wchar_t +/* Py_DEPRECATED(3.3) */ typedef wchar_t Py_UNICODE; + +/* --- Internal Unicode Operations ---------------------------------------- */ + +// Static inline functions to work with surrogates +static inline int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDFFF); +} +static inline int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDBFF); +} +static inline int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) { + return (0xDC00 <= ch && ch <= 0xDFFF); +} + +// Join two surrogate characters and return a single Py_UCS4 value. +static inline Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) { + assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); + assert(Py_UNICODE_IS_LOW_SURROGATE(low)); + return 0x10000 + (((high & 0x03FF) << 10) | (low & 0x03FF)); +} + +// High surrogate = top 10 bits added to 0xD800. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_HIGH_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xD800 - (0x10000 >> 10) + (ch >> 10)); +} + +// Low surrogate = bottom 10 bits added to 0xDC00. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xDC00 + (ch & 0x3FF)); +} + +/* --- Unicode Type ------------------------------------------------------- */ + +/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject + structure. state.ascii and state.compact are set, and the data + immediately follow the structure. utf8_length can be found + in the length field; the utf8 pointer is equal to the data pointer. */ +typedef struct { + /* There are 4 forms of Unicode strings: + + - compact ascii: + + * structure = PyASCIIObject + * test: PyUnicode_IS_COMPACT_ASCII(op) + * kind = PyUnicode_1BYTE_KIND + * compact = 1 + * ascii = 1 + * (length is the length of the utf8) + * (data starts just after the structure) + * (since ASCII is decoded from UTF-8, the utf8 string are the data) + + - compact: + + * structure = PyCompactUnicodeObject + * test: PyUnicode_IS_COMPACT(op) && !PyUnicode_IS_ASCII(op) + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 1 + * ascii = 0 + * utf8 is not shared with data + * utf8_length = 0 if utf8 is NULL + * (data starts just after the structure) + + - legacy string: + + * structure = PyUnicodeObject structure + * test: !PyUnicode_IS_COMPACT(op) + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 0 + * data.any is not NULL + * utf8 is shared and utf8_length = length with data.any if ascii = 1 + * utf8_length = 0 if utf8 is NULL + + Compact strings use only one memory block (structure + characters), + whereas legacy strings use one block for the structure and one block + for characters. + + Legacy strings are created by subclasses of Unicode. + + See also _PyUnicode_CheckConsistency(). + */ + PyObject_HEAD + Py_ssize_t length; /* Number of code points in the string */ + Py_hash_t hash; /* Hash value; -1 if not set */ + struct { + /* If interned is non-zero, the two references from the + dictionary to this object are *not* counted in ob_refcnt. + The possible values here are: + 0: Not Interned + 1: Interned + 2: Interned and Immortal + 3: Interned, Immortal, and Static + This categorization allows the runtime to determine the right + cleanup mechanism at runtime shutdown. */ + unsigned int interned:2; + /* Character size: + + - PyUnicode_1BYTE_KIND (1): + + * character type = Py_UCS1 (8 bits, unsigned) + * all characters are in the range U+0000-U+00FF (latin1) + * if ascii is set, all characters are in the range U+0000-U+007F + (ASCII), otherwise at least one character is in the range + U+0080-U+00FF + + - PyUnicode_2BYTE_KIND (2): + + * character type = Py_UCS2 (16 bits, unsigned) + * all characters are in the range U+0000-U+FFFF (BMP) + * at least one character is in the range U+0100-U+FFFF + + - PyUnicode_4BYTE_KIND (4): + + * character type = Py_UCS4 (32 bits, unsigned) + * all characters are in the range U+0000-U+10FFFF + * at least one character is in the range U+10000-U+10FFFF + */ + unsigned int kind:3; + /* Compact is with respect to the allocation scheme. Compact unicode + objects only require one memory block while non-compact objects use + one block for the PyUnicodeObject struct and another for its data + buffer. */ + unsigned int compact:1; + /* The string only contains characters in the range U+0000-U+007F (ASCII) + and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is + set, use the PyASCIIObject structure. */ + unsigned int ascii:1; + /* The object is statically allocated. */ + unsigned int statically_allocated:1; + /* Padding to ensure that PyUnicode_DATA() is always aligned to + 4 bytes (see issue #19537 on m68k). */ + unsigned int :24; + } state; +} PyASCIIObject; + +/* Non-ASCII strings allocated through PyUnicode_New use the + PyCompactUnicodeObject structure. state.compact is set, and the data + immediately follow the structure. */ +typedef struct { + PyASCIIObject _base; + Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the + * terminating \0. */ + char *utf8; /* UTF-8 representation (null-terminated) */ +} PyCompactUnicodeObject; + +/* Object format for Unicode subclasses. */ +typedef struct { + PyCompactUnicodeObject _base; + union { + void *any; + Py_UCS1 *latin1; + Py_UCS2 *ucs2; + Py_UCS4 *ucs4; + } data; /* Canonical, smallest-form Unicode buffer */ +} PyUnicodeObject; + +PyAPI_FUNC(int) _PyUnicode_CheckConsistency( + PyObject *op, + int check_content); + + +#define _PyASCIIObject_CAST(op) \ + (assert(PyUnicode_Check(op)), \ + _Py_CAST(PyASCIIObject*, (op))) +#define _PyCompactUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), \ + _Py_CAST(PyCompactUnicodeObject*, (op))) +#define _PyUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), \ + _Py_CAST(PyUnicodeObject*, (op))) + + +/* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ + +/* Values for PyASCIIObject.state: */ + +/* Interning state. */ +#define SSTATE_NOT_INTERNED 0 +#define SSTATE_INTERNED_MORTAL 1 +#define SSTATE_INTERNED_IMMORTAL 2 +#define SSTATE_INTERNED_IMMORTAL_STATIC 3 + +/* Use only if you know it's a string */ +static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.interned; +} +#define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) + +/* For backward compatibility */ +static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) { + return 1; +} +#define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op)) + +/* Return true if the string contains only ASCII characters, or 0 if not. The + string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be + ready. */ +static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.ascii; +} +#define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op)) + +/* Return true if the string is compact or 0 if not. + No type checks or Ready calls are performed. */ +static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.compact; +} +#define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op)) + +/* Return true if the string is a compact ASCII string (use PyASCIIObject + structure), or 0 if not. No type checks or Ready calls are performed. */ +static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) { + return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)); +} +#define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op)) + +enum PyUnicode_Kind { +/* Return values of the PyUnicode_KIND() function: */ + PyUnicode_1BYTE_KIND = 1, + PyUnicode_2BYTE_KIND = 2, + PyUnicode_4BYTE_KIND = 4 +}; + +// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above. +// +// gh-89653: Converting this macro to a static inline function would introduce +// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and +// unsigned numbers) where kind type is an int or on +// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned). +#define PyUnicode_KIND(op) _Py_RVALUE(_PyASCIIObject_CAST(op)->state.kind) + +/* Return a void pointer to the raw unicode buffer. */ +static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { + if (PyUnicode_IS_ASCII(op)) { + return _Py_STATIC_CAST(void*, (_PyASCIIObject_CAST(op) + 1)); + } + return _Py_STATIC_CAST(void*, (_PyCompactUnicodeObject_CAST(op) + 1)); +} + +static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) { + void *data; + assert(!PyUnicode_IS_COMPACT(op)); + data = _PyUnicodeObject_CAST(op)->data.any; + assert(data != NULL); + return data; +} + +static inline void* PyUnicode_DATA(PyObject *op) { + if (PyUnicode_IS_COMPACT(op)) { + return _PyUnicode_COMPACT_DATA(op); + } + return _PyUnicode_NONCOMPACT_DATA(op); +} +#define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op)) + +/* Return pointers to the canonical representation cast to unsigned char, + Py_UCS2, or Py_UCS4 for direct character access. + No checks are performed, use PyUnicode_KIND() before to ensure + these will work correctly. */ + +#define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op)) +#define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op)) +#define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op)) + +/* Returns the length of the unicode string. */ +static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { + return _PyASCIIObject_CAST(op)->length; +} +#define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op)) + +/* Write into the canonical representation, this function does not do any sanity + checks and is intended for usage in loops. The caller should cache the + kind and data pointers obtained from other function calls. + index is the index in the string (starts at 0) and value is the new + code point value which should be written to that location. */ +static inline void PyUnicode_WRITE(int kind, void *data, + Py_ssize_t index, Py_UCS4 value) +{ + assert(index >= 0); + if (kind == PyUnicode_1BYTE_KIND) { + assert(value <= 0xffU); + _Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value); + } + else if (kind == PyUnicode_2BYTE_KIND) { + assert(value <= 0xffffU); + _Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + assert(value <= 0x10ffffU); + _Py_STATIC_CAST(Py_UCS4*, data)[index] = value; + } +} +#define PyUnicode_WRITE(kind, data, index, value) \ + PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \ + (index), _Py_STATIC_CAST(Py_UCS4, value)) + +/* Read a code point from the string's canonical representation. No checks + or ready calls are performed. */ +static inline Py_UCS4 PyUnicode_READ(int kind, + const void *data, Py_ssize_t index) +{ + assert(index >= 0); + if (kind == PyUnicode_1BYTE_KIND) { + return _Py_STATIC_CAST(const Py_UCS1*, data)[index]; + } + if (kind == PyUnicode_2BYTE_KIND) { + return _Py_STATIC_CAST(const Py_UCS2*, data)[index]; + } + assert(kind == PyUnicode_4BYTE_KIND); + return _Py_STATIC_CAST(const Py_UCS4*, data)[index]; +} +#define PyUnicode_READ(kind, data, index) \ + PyUnicode_READ(_Py_STATIC_CAST(int, kind), \ + _Py_STATIC_CAST(const void*, data), \ + (index)) + +/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it + calls PyUnicode_KIND() and might call it twice. For single reads, use + PyUnicode_READ_CHAR, for multiple consecutive reads callers should + cache kind and use PyUnicode_READ instead. */ +static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) +{ + int kind; + + assert(index >= 0); + // Tolerate reading the NUL character at str[len(str)] + assert(index <= PyUnicode_GET_LENGTH(unicode)); + + kind = PyUnicode_KIND(unicode); + if (kind == PyUnicode_1BYTE_KIND) { + return PyUnicode_1BYTE_DATA(unicode)[index]; + } + if (kind == PyUnicode_2BYTE_KIND) { + return PyUnicode_2BYTE_DATA(unicode)[index]; + } + assert(kind == PyUnicode_4BYTE_KIND); + return PyUnicode_4BYTE_DATA(unicode)[index]; +} +#define PyUnicode_READ_CHAR(unicode, index) \ + PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) + +/* Return a maximum character value which is suitable for creating another + string based on op. This is always an approximation but more efficient + than iterating over the string. */ +static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) +{ + int kind; + + if (PyUnicode_IS_ASCII(op)) { + return 0x7fU; + } + + kind = PyUnicode_KIND(op); + if (kind == PyUnicode_1BYTE_KIND) { + return 0xffU; + } + if (kind == PyUnicode_2BYTE_KIND) { + return 0xffffU; + } + assert(kind == PyUnicode_4BYTE_KIND); + return 0x10ffffU; +} +#define PyUnicode_MAX_CHAR_VALUE(op) \ + PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) + +/* === Public API ========================================================= */ + +/* --- Plain Py_UNICODE --------------------------------------------------- */ + +/* With PEP 393, this is the recommended way to allocate a new unicode object. + This function will allocate the object and its buffer in a single memory + block. Objects created using this function are not resizable. */ +PyAPI_FUNC(PyObject*) PyUnicode_New( + Py_ssize_t size, /* Number of code points in the new string */ + Py_UCS4 maxchar /* maximum code point value in the string */ + ); + +/* For backward compatibility */ +static inline int PyUnicode_READY(PyObject* Py_UNUSED(op)) +{ + return 0; +} +#define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op)) + +/* Get a copy of a Unicode string. */ +PyAPI_FUNC(PyObject*) _PyUnicode_Copy( + PyObject *unicode + ); + +/* Copy character from one unicode object into another, this function performs + character conversion when necessary and falls back to memcpy() if possible. + + Fail if to is too small (smaller than *how_many* or smaller than + len(from)-from_start), or if kind(from[from_start:from_start+how_many]) > + kind(to), or if *to* has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. + + Pseudo-code: + + how_many = min(how_many, len(from) - from_start) + to[to_start:to_start+how_many] = from[from_start:from_start+how_many] + return how_many + + Note: The function doesn't write a terminating null character. + */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); + +/* Unsafe version of PyUnicode_CopyCharacters(): don't check arguments and so + may crash if parameters are invalid (e.g. if the output string + is too short). */ +PyAPI_FUNC(void) _PyUnicode_FastCopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); + +/* Fill a string with a character: write fill_char into + unicode[start:start+length]. + + Fail if fill_char is bigger than the string maximum character, or if the + string has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); + +/* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash + if parameters are invalid (e.g. if length is longer than the string). */ +PyAPI_FUNC(void) _PyUnicode_FastFill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); + +/* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. + Scan the string to find the maximum character. */ +PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( + int kind, + const void *buffer, + Py_ssize_t size); + +/* Create a new string from a buffer of ASCII characters. + WARNING: Don't check if the string contains any non-ASCII character. */ +PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII( + const char *buffer, + Py_ssize_t size); + +/* Compute the maximum character of the substring unicode[start:end]. + Return 127 for an empty string. */ +PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t end); + +/* --- _PyUnicodeWriter API ----------------------------------------------- */ + +typedef struct { + PyObject *buffer; + void *data; + int kind; + Py_UCS4 maxchar; + Py_ssize_t size; + Py_ssize_t pos; + + /* minimum number of allocated characters (default: 0) */ + Py_ssize_t min_length; + + /* minimum character (default: 127, ASCII) */ + Py_UCS4 min_char; + + /* If non-zero, overallocate the buffer (default: 0). */ + unsigned char overallocate; + + /* If readonly is 1, buffer is a shared string (cannot be modified) + and size is set to 0. */ + unsigned char readonly; +} _PyUnicodeWriter ; + +/* Initialize a Unicode writer. + * + * By default, the minimum buffer size is 0 character and overallocation is + * disabled. Set min_length, min_char and overallocate attributes to control + * the allocation of the buffer. */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); + +/* Prepare the buffer to write 'length' characters + with the specified maximum character. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ + (((MAXCHAR) <= (WRITER)->maxchar \ + && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ + ? 0 \ + : (((LENGTH) == 0) \ + ? 0 \ + : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) + +/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro + instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, + Py_ssize_t length, Py_UCS4 maxchar); + +/* Prepare the buffer to have at least the kind KIND. + For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will + support characters in range U+000-U+FFFF. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ + ((KIND) <= (WRITER)->kind \ + ? 0 \ + : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) + +/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() + macro instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, + int kind); + +/* Append a Unicode character. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, + Py_UCS4 ch + ); + +/* Append a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, + PyObject *str /* Unicode string */ + ); + +/* Append a substring of a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, + PyObject *str, /* Unicode string */ + Py_ssize_t start, + Py_ssize_t end + ); + +/* Append an ASCII-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, + const char *str, /* ASCII-encoded byte string */ + Py_ssize_t len /* number of bytes, or -1 if unknown */ + ); + +/* Append a latin1-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, + const char *str, /* latin1-encoded byte string */ + Py_ssize_t len /* length in bytes */ + ); + +/* Get the value of the writer as a Unicode string. Clear the + buffer of the writer. Raise an exception and return NULL + on error. */ +PyAPI_FUNC(PyObject *) +_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); + + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode. + + Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation + in the unicodeobject. + + _PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to + support the previous internal function with the same behaviour. + + Use of this API is DEPRECATED since no size information can be + extracted from the returned data. +*/ + +PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); + +#define _PyUnicode_AsString PyUnicode_AsUTF8 + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF7( + PyObject *unicode, /* Unicode object */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ); + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( + PyObject *unicode, + const char *errors); + +/* --- UTF-32 Codecs ------------------------------------------------------ */ + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( + PyObject *object, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Returns a Python string object holding the UTF-16 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. +*/ +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( + PyObject* unicode, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +/* Variant of PyUnicode_DecodeUnicodeEscape that supports partial decoding. */ +PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeStateful( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ +); +/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape + chars. */ +PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed, /* bytes consumed */ + const char **first_invalid_escape /* on return, points to first + invalid escaped char in + string. */ +); + +/* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */ + +/* Variant of PyUnicode_DecodeRawUnicodeEscape that supports partial decoding. */ +PyAPI_FUNC(PyObject*) _PyUnicode_DecodeRawUnicodeEscapeStateful( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ +); + +/* --- Latin-1 Codecs ----------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsLatin1String( + PyObject* unicode, + const char* errors); + +/* --- ASCII Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsASCIIString( + PyObject* unicode, + const char* errors); + +/* --- Character Map Codecs ----------------------------------------------- */ + +/* Translate an Unicode object by applying a character mapping table to + it and return the resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. +*/ +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( + PyObject *unicode, /* Unicode object */ + PyObject *mapping, /* encoding mapping */ + const char *errors /* error handling */ + ); + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Coverts a Unicode object holding a decimal value to an ASCII string + for using in int, float and complex parsers. + Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. Transforms spaces to ASCII. + Transforms code points starting from the first non-ASCII code point that + is neither a decimal digit nor a space to the end into '?'. */ + +PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( + PyObject *unicode /* Unicode object */ + ); + +/* --- Methods & Slots ---------------------------------------------------- */ + +PyAPI_FUNC(PyObject *) _PyUnicode_JoinArray( + PyObject *separator, + PyObject *const *items, + Py_ssize_t seqlen + ); + +/* Test whether a unicode is equal to ASCII identifier. Return 1 if true, + 0 otherwise. The right argument must be ASCII identifier. + Any error occurs inside will be cleared before return. */ +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( + PyObject *left, /* Left string */ + _Py_Identifier *right /* Right identifier */ + ); + +/* Test whether a unicode is equal to ASCII string. Return 1 if true, + 0 otherwise. The right argument must be ASCII-encoded string. + Any error occurs inside will be cleared before return. */ +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( + PyObject *left, + const char *right /* ASCII-encoded string */ + ); + +/* Externally visible for str.strip(unicode) */ +PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( + PyObject *self, + int striptype, + PyObject *sepobj + ); + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( + _PyUnicodeWriter *writer, + Py_ssize_t n_buffer, + PyObject *digits, + Py_ssize_t d_pos, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + PyObject *thousands_sep, + Py_UCS4 *maxchar); + +/* === Characters Type APIs =============================================== */ + +/* These should not be used directly. Use the Py_UNICODE_IS* and + Py_UNICODE_TO* macros instead. + + These APIs are implemented in Objects/unicodectype.c. + +*/ + +PyAPI_FUNC(int) _PyUnicode_IsLowercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsUppercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsTitlecase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidStart( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidContinue( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsWhitespace( + const Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsLinebreak( + const Py_UCS4 ch /* Unicode character */ + ); + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( + Py_UCS4 ch /* Unicode character */ + ); + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( + Py_UCS4 ch /* Unicode character */ + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToLowerFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToTitleFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToUpperFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToFoldedFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsCased( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(double) _PyUnicode_ToNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsPrintable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UCS4 ch /* Unicode character */ + ); + +// Helper array used by Py_UNICODE_ISSPACE(). +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +// Since splitting on whitespace is an important use case, and +// whitespace in most situations is solely ASCII whitespace, we +// optimize for the common case by using a quick look-up table +// _Py_ascii_whitespace (see below) with an inlined check. +static inline int Py_UNICODE_ISSPACE(Py_UCS4 ch) { + if (ch < 128) { + return _Py_ascii_whitespace[ch]; + } + return _PyUnicode_IsWhitespace(ch); +} + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) { + return (Py_UNICODE_ISALPHA(ch) + || Py_UNICODE_ISDECIMAL(ch) + || Py_UNICODE_ISDIGIT(ch) + || Py_UNICODE_ISNUMERIC(ch)); +} + + +/* === Misc functions ===================================================== */ + +PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); + +/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ +PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); + +/* Fast equality check when the inputs are known to be exact unicode types + and where the hash values are equal (i.e. a very probable match) */ +PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); + +/* Equality check. */ +PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); + +PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); + +PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); diff --git a/contrib/tools/python3/Include/cpython/warnings.h b/contrib/tools/python3/Include/cpython/warnings.h new file mode 100644 index 0000000000..4e3eb88e8f --- /dev/null +++ b/contrib/tools/python3/Include/cpython/warnings.h @@ -0,0 +1,20 @@ +#ifndef Py_CPYTHON_WARNINGS_H +# error "this header file must not be included directly" +#endif + +PyAPI_FUNC(int) PyErr_WarnExplicitObject( + PyObject *category, + PyObject *message, + PyObject *filename, + int lineno, + PyObject *module, + PyObject *registry); + +PyAPI_FUNC(int) PyErr_WarnExplicitFormat( + PyObject *category, + const char *filename, int lineno, + const char *module, PyObject *registry, + const char *format, ...); + +// DEPRECATED: Use PyErr_WarnEx() instead. +#define PyErr_Warn(category, msg) PyErr_WarnEx((category), (msg), 1) diff --git a/contrib/tools/python3/Include/cpython/weakrefobject.h b/contrib/tools/python3/Include/cpython/weakrefobject.h new file mode 100644 index 0000000000..fd79fdc2dc --- /dev/null +++ b/contrib/tools/python3/Include/cpython/weakrefobject.h @@ -0,0 +1,56 @@ +#ifndef Py_CPYTHON_WEAKREFOBJECT_H +# error "this header file must not be included directly" +#endif + +/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, + * and CallableProxyType. + */ +struct _PyWeakReference { + PyObject_HEAD + + /* The object to which this is a weak reference, or Py_None if none. + * Note that this is a stealth reference: wr_object's refcount is + * not incremented to reflect this pointer. + */ + PyObject *wr_object; + + /* A callable to invoke when wr_object dies, or NULL if none. */ + PyObject *wr_callback; + + /* A cache for wr_object's hash code. As usual for hashes, this is -1 + * if the hash code isn't known yet. + */ + Py_hash_t hash; + + /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- + * terminated list of weak references to it. These are the list pointers. + * If wr_object goes away, wr_object is set to Py_None, and these pointers + * have no meaning then. + */ + PyWeakReference *wr_prev; + PyWeakReference *wr_next; + vectorcallfunc vectorcall; +}; + +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); + +PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); + +static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { + PyWeakReference *ref; + PyObject *obj; + assert(PyWeakref_Check(ref_obj)); + ref = _Py_CAST(PyWeakReference*, ref_obj); + obj = ref->wr_object; + // Explanation for the Py_REFCNT() check: when a weakref's target is part + // of a long chain of deallocations which triggers the trashcan mechanism, + // clearing the weakrefs can be delayed long after the target's refcount + // has dropped to zero. In the meantime, code accessing the weakref will + // be able to "see" the target object even though it is supposed to be + // unreachable. See issue gh-60806. + if (Py_REFCNT(obj) > 0) { + return obj; + } + return Py_None; +} +#define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref)) |