Type Objects¶
Perhaps one of the most important structures of the Python object system is the structure that defines a new type: the :ctype:`PyTypeObject` structure. Type objects can be handled using any of the :cfunc:`PyObject_\*` or :cfunc:`PyType_\*` functions, but do not offer much that’s interesting to most Python applications. These objects are fundamental to how objects behave, so they are very important to the interpreter itself and to any extension module that implements new types.
Type objects are fairly large compared to most of the standard types. The reason for the size is that each type object stores a large number of values, mostly C function pointers, each of which implements a small part of the type’s functionality. The fields of the type object are examined in detail in this section. The fields will be described in the order in which they occur in the structure.
Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc
The structure definition for :ctype:`PyTypeObject` can be found in
Include/object.h
. For convenience of reference, this repeats the
definition found there:
typedef struct _typeobject {
PyObject_VAR_HEAD
char *tp_name; /* For printing, in format "<module>.<name>" */
int tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
cmpfunc tp_compare;
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 */
long tp_flags;
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 */
long tp_weaklistoffset;
/* Added in release 2.2 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
long 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;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
} PyTypeObject;
The type object structure extends the :ctype:`PyVarObject` structure. The
ob_size
field is used for dynamic types (created by type_new()
,
usually called from a class statement). Note that :cdata:`PyType_Type` (the
metatype) initializes tp_itemsize
, which means that its instances (i.e.
type objects) must have the ob_size
field.
The following three fields only exist if the
Py_TPFLAGS_HAVE_RICHCOMPARE
flag bit is set.
The next field only exists if the Py_TPFLAGS_HAVE_WEAKREFS
flag bit is
set.
The next two fields only exist if the Py_TPFLAGS_HAVE_ITER
flag bit is
set.
The next fields, up to and including tp_weaklist
, only exist if the
Py_TPFLAGS_HAVE_CLASS
flag bit is set.
The remaining fields are only defined if the feature test macro
COUNT_ALLOCS
is defined, and are for internal use only. They are
documented here for completeness. None of these fields are inherited by
subtypes.
Also, note that, in a garbage collected Python, tp_dealloc may be called from any Python thread, not just the thread which created the object (if the object becomes part of a refcount cycle, that cycle might be collected by a garbage collection on any thread). This is not a problem for Python API calls, since the thread on which tp_dealloc is called will own the Global Interpreter Lock (GIL). However, if the object being destroyed in turn destroys objects from some other C or C++ library, care should be taken to ensure that destroying those objects on the thread which called tp_dealloc will not violate any assumptions of the library.
Number Object Structures¶
Binary and ternary functions may receive different kinds of arguments, depending
on the flag bit Py_TPFLAGS_CHECKTYPES
:
- If
Py_TPFLAGS_CHECKTYPES
is not set, the function arguments are guaranteed to be of the object’s type; the caller is responsible for calling the coercion method specified by thenb_coerce
member to convert the arguments: - If the
Py_TPFLAGS_CHECKTYPES
flag is set, binary and ternary functions must check the type of all their operands, and implement the necessary conversions (at least one of the operands is an instance of the defined type). This is the recommended way; with Python 3.0 coercion will disappear completely.
If the operation is not defined for the given operands, binary and ternary
functions must return Py_NotImplemented
, if another error occurred they must
return NULL
and set an exception.
Mapping Object Structures¶
Sequence Object Structures¶
Buffer Object Structures¶
The buffer interface exports a model where an object can expose its internal data as a set of chunks of data, where each chunk is specified as a pointer/length pair. These chunks are called segments and are presumed to be non-contiguous in memory.
If an object does not export the buffer interface, then its tp_as_buffer
member in the :ctype:`PyTypeObject` structure should be NULL. Otherwise, the
tp_as_buffer
will point to a :ctype:`PyBufferProcs` structure.
Note
It is very important that your :ctype:`PyTypeObject` structure uses
Py_TPFLAGS_DEFAULT
for the value of the tp_flags
member rather
than 0
. This tells the Python runtime that your :ctype:`PyBufferProcs`
structure contains the bf_getcharbuffer
slot. Older versions of Python
did not have this member, so a new Python interpreter using an old extension
needs to be able to test for its presence before using it.
-
Py_TPFLAGS_HAVE_GETCHARBUFFER
¶ Flag bit set in the type structure to indicate that the
bf_getcharbuffer
slot is known. This being set does not indicate that the object supports the buffer interface or that thebf_getcharbuffer
slot is non-NULL.