jpayne@69: #ifndef Py_CPYTHON_OBJECT_H jpayne@69: # error "this header file must not be included directly" jpayne@69: #endif jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: extern "C" { jpayne@69: #endif jpayne@69: jpayne@69: /********************* String Literals ****************************************/ jpayne@69: /* This structure helps managing static strings. The basic usage goes like this: jpayne@69: Instead of doing jpayne@69: jpayne@69: r = PyObject_CallMethod(o, "foo", "args", ...); jpayne@69: jpayne@69: do jpayne@69: jpayne@69: _Py_IDENTIFIER(foo); jpayne@69: ... jpayne@69: r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); jpayne@69: jpayne@69: PyId_foo is a static variable, either on block level or file level. On first jpayne@69: usage, the string "foo" is interned, and the structures are linked. On interpreter jpayne@69: shutdown, all strings are released (through _PyUnicode_ClearStaticStrings). jpayne@69: jpayne@69: Alternatively, _Py_static_string allows choosing the variable name. jpayne@69: _PyUnicode_FromId returns a borrowed reference to the interned string. jpayne@69: _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. jpayne@69: */ jpayne@69: typedef struct _Py_Identifier { jpayne@69: struct _Py_Identifier *next; jpayne@69: const char* string; jpayne@69: PyObject *object; jpayne@69: } _Py_Identifier; jpayne@69: jpayne@69: #define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL } jpayne@69: #define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) jpayne@69: #define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) jpayne@69: jpayne@69: /* buffer interface */ jpayne@69: typedef struct bufferinfo { jpayne@69: void *buf; jpayne@69: PyObject *obj; /* owned reference */ jpayne@69: Py_ssize_t len; jpayne@69: Py_ssize_t itemsize; /* This is Py_ssize_t so it can be jpayne@69: pointed to by strides in simple case.*/ jpayne@69: int readonly; jpayne@69: int ndim; jpayne@69: char *format; jpayne@69: Py_ssize_t *shape; jpayne@69: Py_ssize_t *strides; jpayne@69: Py_ssize_t *suboffsets; jpayne@69: void *internal; jpayne@69: } Py_buffer; jpayne@69: jpayne@69: typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); jpayne@69: typedef void (*releasebufferproc)(PyObject *, Py_buffer *); jpayne@69: jpayne@69: typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, jpayne@69: size_t nargsf, PyObject *kwnames); jpayne@69: jpayne@69: /* Maximum number of dimensions */ jpayne@69: #define PyBUF_MAX_NDIM 64 jpayne@69: jpayne@69: /* Flags for getting buffers */ jpayne@69: #define PyBUF_SIMPLE 0 jpayne@69: #define PyBUF_WRITABLE 0x0001 jpayne@69: /* we used to include an E, backwards compatible alias */ jpayne@69: #define PyBUF_WRITEABLE PyBUF_WRITABLE jpayne@69: #define PyBUF_FORMAT 0x0004 jpayne@69: #define PyBUF_ND 0x0008 jpayne@69: #define PyBUF_STRIDES (0x0010 | PyBUF_ND) jpayne@69: #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) jpayne@69: #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) jpayne@69: #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) jpayne@69: #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) jpayne@69: jpayne@69: #define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) jpayne@69: #define PyBUF_CONTIG_RO (PyBUF_ND) jpayne@69: jpayne@69: #define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) jpayne@69: #define PyBUF_STRIDED_RO (PyBUF_STRIDES) jpayne@69: jpayne@69: #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) jpayne@69: #define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) jpayne@69: jpayne@69: #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) jpayne@69: #define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) jpayne@69: jpayne@69: jpayne@69: #define PyBUF_READ 0x100 jpayne@69: #define PyBUF_WRITE 0x200 jpayne@69: /* End buffer interface */ jpayne@69: jpayne@69: jpayne@69: typedef struct { jpayne@69: /* Number implementations must check *both* jpayne@69: arguments for proper type and implement the necessary conversions jpayne@69: in the slot functions themselves. */ jpayne@69: jpayne@69: binaryfunc nb_add; jpayne@69: binaryfunc nb_subtract; jpayne@69: binaryfunc nb_multiply; jpayne@69: binaryfunc nb_remainder; jpayne@69: binaryfunc nb_divmod; jpayne@69: ternaryfunc nb_power; jpayne@69: unaryfunc nb_negative; jpayne@69: unaryfunc nb_positive; jpayne@69: unaryfunc nb_absolute; jpayne@69: inquiry nb_bool; jpayne@69: unaryfunc nb_invert; jpayne@69: binaryfunc nb_lshift; jpayne@69: binaryfunc nb_rshift; jpayne@69: binaryfunc nb_and; jpayne@69: binaryfunc nb_xor; jpayne@69: binaryfunc nb_or; jpayne@69: unaryfunc nb_int; jpayne@69: void *nb_reserved; /* the slot formerly known as nb_long */ jpayne@69: unaryfunc nb_float; jpayne@69: jpayne@69: binaryfunc nb_inplace_add; jpayne@69: binaryfunc nb_inplace_subtract; jpayne@69: binaryfunc nb_inplace_multiply; jpayne@69: binaryfunc nb_inplace_remainder; jpayne@69: ternaryfunc nb_inplace_power; jpayne@69: binaryfunc nb_inplace_lshift; jpayne@69: binaryfunc nb_inplace_rshift; jpayne@69: binaryfunc nb_inplace_and; jpayne@69: binaryfunc nb_inplace_xor; jpayne@69: binaryfunc nb_inplace_or; jpayne@69: jpayne@69: binaryfunc nb_floor_divide; jpayne@69: binaryfunc nb_true_divide; jpayne@69: binaryfunc nb_inplace_floor_divide; jpayne@69: binaryfunc nb_inplace_true_divide; jpayne@69: jpayne@69: unaryfunc nb_index; jpayne@69: jpayne@69: binaryfunc nb_matrix_multiply; jpayne@69: binaryfunc nb_inplace_matrix_multiply; jpayne@69: } PyNumberMethods; jpayne@69: jpayne@69: typedef struct { jpayne@69: lenfunc sq_length; jpayne@69: binaryfunc sq_concat; jpayne@69: ssizeargfunc sq_repeat; jpayne@69: ssizeargfunc sq_item; jpayne@69: void *was_sq_slice; jpayne@69: ssizeobjargproc sq_ass_item; jpayne@69: void *was_sq_ass_slice; jpayne@69: objobjproc sq_contains; jpayne@69: jpayne@69: binaryfunc sq_inplace_concat; jpayne@69: ssizeargfunc sq_inplace_repeat; jpayne@69: } PySequenceMethods; jpayne@69: jpayne@69: typedef struct { jpayne@69: lenfunc mp_length; jpayne@69: binaryfunc mp_subscript; jpayne@69: objobjargproc mp_ass_subscript; jpayne@69: } PyMappingMethods; jpayne@69: jpayne@69: typedef struct { jpayne@69: unaryfunc am_await; jpayne@69: unaryfunc am_aiter; jpayne@69: unaryfunc am_anext; jpayne@69: } PyAsyncMethods; jpayne@69: jpayne@69: typedef struct { jpayne@69: getbufferproc bf_getbuffer; jpayne@69: releasebufferproc bf_releasebuffer; jpayne@69: } PyBufferProcs; jpayne@69: jpayne@69: /* Allow printfunc in the tp_vectorcall_offset slot for jpayne@69: * backwards-compatibility */ jpayne@69: typedef Py_ssize_t printfunc; jpayne@69: jpayne@69: typedef struct _typeobject { jpayne@69: PyObject_VAR_HEAD jpayne@69: const char *tp_name; /* For printing, in format "." */ jpayne@69: Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ jpayne@69: jpayne@69: /* Methods to implement standard operations */ jpayne@69: jpayne@69: destructor tp_dealloc; jpayne@69: Py_ssize_t tp_vectorcall_offset; jpayne@69: getattrfunc tp_getattr; jpayne@69: setattrfunc tp_setattr; jpayne@69: PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) jpayne@69: or tp_reserved (Python 3) */ jpayne@69: reprfunc tp_repr; jpayne@69: jpayne@69: /* Method suites for standard classes */ jpayne@69: jpayne@69: PyNumberMethods *tp_as_number; jpayne@69: PySequenceMethods *tp_as_sequence; jpayne@69: PyMappingMethods *tp_as_mapping; jpayne@69: jpayne@69: /* More standard operations (here for binary compatibility) */ jpayne@69: jpayne@69: hashfunc tp_hash; jpayne@69: ternaryfunc tp_call; jpayne@69: reprfunc tp_str; jpayne@69: getattrofunc tp_getattro; jpayne@69: setattrofunc tp_setattro; jpayne@69: jpayne@69: /* Functions to access object as input/output buffer */ jpayne@69: PyBufferProcs *tp_as_buffer; jpayne@69: jpayne@69: /* Flags to define presence of optional/expanded features */ jpayne@69: unsigned long tp_flags; jpayne@69: jpayne@69: const char *tp_doc; /* Documentation string */ jpayne@69: jpayne@69: /* Assigned meaning in release 2.0 */ jpayne@69: /* call function for all accessible objects */ jpayne@69: traverseproc tp_traverse; jpayne@69: jpayne@69: /* delete references to contained objects */ jpayne@69: inquiry tp_clear; jpayne@69: jpayne@69: /* Assigned meaning in release 2.1 */ jpayne@69: /* rich comparisons */ jpayne@69: richcmpfunc tp_richcompare; jpayne@69: jpayne@69: /* weak reference enabler */ jpayne@69: Py_ssize_t tp_weaklistoffset; jpayne@69: jpayne@69: /* Iterators */ jpayne@69: getiterfunc tp_iter; jpayne@69: iternextfunc tp_iternext; jpayne@69: jpayne@69: /* Attribute descriptor and subclassing stuff */ jpayne@69: struct PyMethodDef *tp_methods; jpayne@69: struct PyMemberDef *tp_members; jpayne@69: struct PyGetSetDef *tp_getset; jpayne@69: struct _typeobject *tp_base; jpayne@69: PyObject *tp_dict; jpayne@69: descrgetfunc tp_descr_get; jpayne@69: descrsetfunc tp_descr_set; jpayne@69: Py_ssize_t tp_dictoffset; jpayne@69: initproc tp_init; jpayne@69: allocfunc tp_alloc; jpayne@69: newfunc tp_new; jpayne@69: freefunc tp_free; /* Low-level free-memory routine */ jpayne@69: inquiry tp_is_gc; /* For PyObject_IS_GC */ jpayne@69: PyObject *tp_bases; jpayne@69: PyObject *tp_mro; /* method resolution order */ jpayne@69: PyObject *tp_cache; jpayne@69: PyObject *tp_subclasses; jpayne@69: PyObject *tp_weaklist; jpayne@69: destructor tp_del; jpayne@69: jpayne@69: /* Type attribute cache version tag. Added in version 2.6 */ jpayne@69: unsigned int tp_version_tag; jpayne@69: jpayne@69: destructor tp_finalize; jpayne@69: vectorcallfunc tp_vectorcall; jpayne@69: jpayne@69: /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */ jpayne@69: Py_DEPRECATED(3.8) int (*tp_print)(PyObject *, FILE *, int); jpayne@69: jpayne@69: #ifdef COUNT_ALLOCS jpayne@69: /* these must be last and never explicitly initialized */ jpayne@69: Py_ssize_t tp_allocs; jpayne@69: Py_ssize_t tp_frees; jpayne@69: Py_ssize_t tp_maxalloc; jpayne@69: struct _typeobject *tp_prev; jpayne@69: struct _typeobject *tp_next; jpayne@69: #endif jpayne@69: } PyTypeObject; jpayne@69: jpayne@69: /* The *real* layout of a type object when allocated on the heap */ jpayne@69: typedef struct _heaptypeobject { jpayne@69: /* Note: there's a dependency on the order of these members jpayne@69: in slotptr() in typeobject.c . */ jpayne@69: PyTypeObject ht_type; jpayne@69: PyAsyncMethods as_async; jpayne@69: PyNumberMethods as_number; jpayne@69: PyMappingMethods as_mapping; jpayne@69: PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, jpayne@69: so that the mapping wins when both jpayne@69: the mapping and the sequence define jpayne@69: a given operator (e.g. __getitem__). jpayne@69: see add_operators() in typeobject.c . */ jpayne@69: PyBufferProcs as_buffer; jpayne@69: PyObject *ht_name, *ht_slots, *ht_qualname; jpayne@69: struct _dictkeysobject *ht_cached_keys; jpayne@69: /* here are optional user slots, followed by the members. */ jpayne@69: } PyHeapTypeObject; jpayne@69: jpayne@69: /* access macro to the members which are floating "behind" the object */ jpayne@69: #define PyHeapType_GET_MEMBERS(etype) \ jpayne@69: ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) jpayne@69: jpayne@69: PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); jpayne@69: PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); jpayne@69: PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); jpayne@69: PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); jpayne@69: PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); jpayne@69: PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); jpayne@69: PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); jpayne@69: jpayne@69: struct _Py_Identifier; jpayne@69: PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); jpayne@69: PyAPI_FUNC(void) _Py_BreakPoint(void); jpayne@69: PyAPI_FUNC(void) _PyObject_Dump(PyObject *); jpayne@69: PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); jpayne@69: jpayne@69: PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); jpayne@69: PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); jpayne@69: PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); jpayne@69: PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); jpayne@69: /* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which jpayne@69: don't raise AttributeError. jpayne@69: jpayne@69: Return 1 and set *result != NULL if an attribute is found. jpayne@69: Return 0 and set *result == NULL if an attribute is not found; jpayne@69: an AttributeError is silenced. jpayne@69: Return -1 and set *result == NULL if an error other than AttributeError jpayne@69: is raised. jpayne@69: */ jpayne@69: PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); jpayne@69: PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **); jpayne@69: PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); jpayne@69: PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); jpayne@69: PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); jpayne@69: PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); jpayne@69: jpayne@69: /* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes jpayne@69: dict as the last parameter. */ jpayne@69: PyAPI_FUNC(PyObject *) jpayne@69: _PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); jpayne@69: PyAPI_FUNC(int) jpayne@69: _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, jpayne@69: PyObject *, PyObject *); jpayne@69: jpayne@69: #define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) jpayne@69: jpayne@69: static inline void _Py_Dealloc_inline(PyObject *op) jpayne@69: { jpayne@69: destructor dealloc = Py_TYPE(op)->tp_dealloc; jpayne@69: #ifdef Py_TRACE_REFS jpayne@69: _Py_ForgetReference(op); jpayne@69: #else jpayne@69: _Py_INC_TPFREES(op); jpayne@69: #endif jpayne@69: (*dealloc)(op); jpayne@69: } jpayne@69: #define _Py_Dealloc(op) _Py_Dealloc_inline(op) jpayne@69: jpayne@69: jpayne@69: /* Safely decref `op` and set `op` to `op2`. jpayne@69: * jpayne@69: * As in case of Py_CLEAR "the obvious" code can be deadly: jpayne@69: * jpayne@69: * Py_DECREF(op); jpayne@69: * op = op2; jpayne@69: * jpayne@69: * The safe way is: jpayne@69: * jpayne@69: * Py_SETREF(op, op2); jpayne@69: * jpayne@69: * That arranges to set `op` to `op2` _before_ decref'ing, so that any code jpayne@69: * triggered as a side-effect of `op` getting torn down no longer believes jpayne@69: * `op` points to a valid object. jpayne@69: * jpayne@69: * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of jpayne@69: * Py_DECREF. jpayne@69: */ jpayne@69: jpayne@69: #define Py_SETREF(op, op2) \ jpayne@69: do { \ jpayne@69: PyObject *_py_tmp = _PyObject_CAST(op); \ jpayne@69: (op) = (op2); \ jpayne@69: Py_DECREF(_py_tmp); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define Py_XSETREF(op, op2) \ jpayne@69: do { \ jpayne@69: PyObject *_py_tmp = _PyObject_CAST(op); \ jpayne@69: (op) = (op2); \ jpayne@69: Py_XDECREF(_py_tmp); \ jpayne@69: } while (0) jpayne@69: jpayne@69: jpayne@69: PyAPI_DATA(PyTypeObject) _PyNone_Type; jpayne@69: PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; jpayne@69: jpayne@69: /* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. jpayne@69: * Defined in object.c. jpayne@69: */ jpayne@69: PyAPI_DATA(int) _Py_SwappedOp[]; jpayne@69: jpayne@69: /* This is the old private API, invoked by the macros before 3.2.4. jpayne@69: Kept for binary compatibility of extensions using the stable ABI. */ jpayne@69: PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); jpayne@69: PyAPI_FUNC(void) _PyTrash_destroy_chain(void); jpayne@69: jpayne@69: PyAPI_FUNC(void) jpayne@69: _PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, jpayne@69: size_t sizeof_block); jpayne@69: PyAPI_FUNC(void) jpayne@69: _PyObject_DebugTypeStats(FILE *out); jpayne@69: jpayne@69: /* Define a pair of assertion macros: jpayne@69: _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). jpayne@69: jpayne@69: These work like the regular C assert(), in that they will abort the jpayne@69: process with a message on stderr if the given condition fails to hold, jpayne@69: but compile away to nothing if NDEBUG is defined. jpayne@69: jpayne@69: However, before aborting, Python will also try to call _PyObject_Dump() on jpayne@69: the given object. This may be of use when investigating bugs in which a jpayne@69: particular object is corrupt (e.g. buggy a tp_visit method in an extension jpayne@69: module breaking the garbage collector), to help locate the broken objects. jpayne@69: jpayne@69: The WITH_MSG variant allows you to supply an additional message that Python jpayne@69: will attempt to print to stderr, after the object dump. */ jpayne@69: #ifdef NDEBUG jpayne@69: /* No debugging: compile away the assertions: */ jpayne@69: # define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ jpayne@69: ((void)0) jpayne@69: #else jpayne@69: /* With debugging: generate checks: */ jpayne@69: # define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ jpayne@69: ((expr) \ jpayne@69: ? (void)(0) \ jpayne@69: : _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \ jpayne@69: (msg), (filename), (lineno), (func))) jpayne@69: #endif jpayne@69: jpayne@69: #define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ jpayne@69: _PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__) jpayne@69: #define _PyObject_ASSERT(obj, expr) \ jpayne@69: _PyObject_ASSERT_WITH_MSG(obj, expr, NULL) jpayne@69: jpayne@69: #define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ jpayne@69: _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) jpayne@69: jpayne@69: /* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined, jpayne@69: to avoid causing compiler/linker errors when building extensions without jpayne@69: NDEBUG against a Python built with NDEBUG defined. jpayne@69: jpayne@69: msg, expr and function can be NULL. */ jpayne@69: PyAPI_FUNC(void) _PyObject_AssertFailed( jpayne@69: PyObject *obj, jpayne@69: const char *expr, jpayne@69: const char *msg, jpayne@69: const char *file, jpayne@69: int line, jpayne@69: const char *function); jpayne@69: jpayne@69: /* Check if an object is consistent. For example, ensure that the reference jpayne@69: counter is greater than or equal to 1, and ensure that ob_type is not NULL. jpayne@69: jpayne@69: Call _PyObject_AssertFailed() if the object is inconsistent. jpayne@69: jpayne@69: If check_content is zero, only check header fields: reduce the overhead. jpayne@69: jpayne@69: The function always return 1. The return value is just here to be able to jpayne@69: write: jpayne@69: jpayne@69: assert(_PyObject_CheckConsistency(obj, 1)); */ jpayne@69: PyAPI_FUNC(int) _PyObject_CheckConsistency( jpayne@69: PyObject *op, jpayne@69: int check_content); jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: } jpayne@69: #endif