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 the nb_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 the bf_getcharbuffer slot is non-NULL.