: PyTypeObject Python 1 PyObject_*() PyType_*() Python

(standard type) C

Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc

PyTypeObject Include/object.h :

typedef 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;
    printfunc tp_print;
    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 */

    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* 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 */
    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;
    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;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;
    destructor tp_del;

    /* Type attribute cache version tag. Added in version 2.6 */
    unsigned int tp_version_tag;

    destructor tp_finalize;

} PyTypeObject;

PyVarObject ob_size ( class type_new() ) PyType_Type () tp_itemsize () ob_size

PyObject* PyObject._ob_next
PyObject* PyObject._ob_prev

Py_TRACE_REFS PyObject_HEAD_INIT NULL NULL ; PYTHONDUMPREFS

Py_ssize_t PyObject.ob_refcnt

PyObject_HEAD_INIT 1 (ob_type )

PyTypeObject* PyObject.ob_type

PyObject_HEAD_INIT &PyType_Type () Windows PyObject_HEAD_INIT NULL :

Foo_Type.ob_type = &PyType_Type;

PyType_Ready() ob_type NULL NULL ob_type ob_type PyType_Ready()

Py_ssize_t PyVarObject.ob_size

const char* PyTypeObject.tp_name

NUL ; P Q M T tp_name "P.Q.M.T"

'__module__'

tp_name __module__ __name__

tp_name __name__ __module__ () pickle pydoc

Py_ssize_t PyTypeObject.tp_basicsize
Py_ssize_t PyTypeObject.tp_itemsize

: tp_itemsize tp_itemsize tp_basicsize

ob_size N "" tp_basicsize tp_itemsize N N ob_size : ob_size N abs(ob_size) ob_size ( ob_size )

PyObject_HEAD PyObject_VAR_HEAD () _ob_prev _ob_next tp_basicsize sizeof GC

0 tp_itemsize 0 tp_itemsize

: tp_basicsize : double tp_itemsize sizeof(double) tp_basicsize sizeof(double) ( double )

destructor PyTypeObject.tp_dealloc

( None Ellipsis )

Py_DECREF() Py_XDECREF() () () tp_free (Py_TPFLAGS_BASETYPE ) tp_free (deallocator) ; PyObject_New() PyObject_VarNew() PyObject_Del() PyObject_GC_New() PyObject_GC_NewVar() PyObject_GC_Del()

printfunc PyTypeObject.tp_print

Python 2.x

getattrfunc PyTypeObject.tp_getattr

get-attribute-string

tp_getattro Python C :

PyObject * tp_getattr(PyObject *o, char *attr_name);

tp_getattro : tp_getattr tp_getattro NULL tp_getattr tp_getattro

setattrfunc PyTypeObject.tp_setattr

tp_setattro Python C :

PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);

v NULL tp_setattro : tp_setattr tp_setattro NULL tp_setattr tp_setattro

PyAsyncMethods* tp_as_async

C awaitable asynchronous iterator async

3.5 : tp_compare tp_reserved

reprfunc PyTypeObject.tp_repr

repr()

PyObject_Repr() Unicode eval() '<' '>'

<%s object at %p> %s %p

PyNumberMethods* tp_as_number

tp_as_number

PySequenceMethods* tp_as_sequence

tp_as_sequence

PyMappingMethods* tp_as_mapping

tp_as_mapping

hashfunc PyTypeObject.tp_hash

hash()

PyObject_Hash() Py_hash_t -1 ; -1

PyObject_HashNotImplemented() type Python __hash__ = None isinstance(o, collections.Hashable) False - Python __hash__ = None tp_hash PyObject_HashNotImplemented()

TypeError

tp_richcompare : tp_richcompare tp_hash NULL tp_richcompare tp_hash

ternaryfunc PyTypeObject.tp_call

NULL PyObject_Call()

reprfunc PyTypeObject.tp_str

str() (str str() str PyObject_Str() PyObject_Str() )

PyObject_Str() ; Unicode " (friendly)" print()

PyObject_Repr()

getattrofunc PyTypeObject.tp_getattro

get-attribute

PyObject_GetAttr() PyObject_GenericGetAttr()

tp_getattr : tp_getattr tp_getattro NULL tp_getattr tp_getattro

setattrofunc PyTypeObject.tp_setattro

PyObject_SetAttr() v NULL PyObject_GenericSetAttr()

tp_setattr : tp_setattr tp_setattro NULL tp_setattr tp_setattro

PyBufferProcs* PyTypeObject.tp_as_buffer

(buffer object structure)

tp_as_buffer

unsigned long PyTypeObject.tp_flags

; ( tp_as_number tp_as_sequence tp_as_mapping tp_as_buffer ) ; NULL

Py_TPFLAGS_HAVE_GC tp_traverse tp_clear Py_TPFLAGS_HAVE_GC tp_traverse tp_clear NULL

; | tp_flags PyType_HasFeature() tp f tp->tp_flags & f

Py_TPFLAGS_HEAPTYPE

ob_type INCREF DECREF (; ob_type INCREF DECREF )

Py_TPFLAGS_BASETYPE

(Java "final" )

Py_TPFLAGS_READY

PyType_Ready()

Py_TPFLAGS_READYING

PyType_Ready()

Py_TPFLAGS_HAVE_GC

(GC) PyObject_GC_New() PyObject_GC_Del() GC tp_traverse tp_clear

Py_TPFLAGS_DEFAULT

: Py_TPFLAGS_HAVE_STACKLESS_EXTENSION Py_TPFLAGS_HAVE_VERSION_TAG

Py_TPFLAGS_LONG_SUBCLASS
Py_TPFLAGS_LIST_SUBCLASS
Py_TPFLAGS_TUPLE_SUBCLASS
Py_TPFLAGS_BYTES_SUBCLASS
Py_TPFLAGS_UNICODE_SUBCLASS
Py_TPFLAGS_DICT_SUBCLASS
Py_TPFLAGS_BASE_EXC_SUBCLASS
Py_TPFLAGS_TYPE_SUBCLASS

PyLong_Check() ; PyObject_IsInstance() tp_flags

Py_TPFLAGS_HAVE_FINALIZE

tp_finalize

3.4 .

const char* PyTypeObject.tp_doc

docstring NUL C __doc__

traverseproc PyTypeObject.tp_traverse

(traversal function) Py_TPFLAGS_HAVE_GC Python

tp_traverse tp_traverse Python Py_VISIT() _thread local_traverse() :

static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
    Py_VISIT(self->args);
    Py_VISIT(self->kw);
    Py_VISIT(self->dict);
    return 0;
}

Py_VISIT() self->key NULL Python

gc get_referents()

Py_VISIT() local_traverse() visit arg

tp_clear Py_TPFLAGS_HAVE_GC : tp_traverse tp_clear tp_traverse tp_clear

inquiry PyTypeObject.tp_clear

(clear function) Py_TPFLAGS_HAVE_GC

tp_clear GC tp_clear (: tp_clear ) tp_clear tp_clear tp_clear tp_clear

tp_clear Python NULL :

static int
local_clear(localobject *self)
{
    Py_CLEAR(self->key);
    Py_CLEAR(self->args);
    Py_CLEAR(self->kw);
    Py_CLEAR(self->dict);
    return 0;
}

Py_CLEAR() : NULL () Python self NULL self Py_CLEAR()

tp_clear Python Python Python tp_dealloc tp_clear

Python

tp_traverse Py_TPFLAGS_HAVE_GC : tp_traverse tp_clear tp_traverse tp_clear

richcmpfunc PyTypeObject.tp_richcompare

PyObject *tp_richcompare(PyObject *a, PyObject *b, int op) 1 PyTypeObject

( Py_True Py_False ) Py_NotImplemented NULL

( == != < ) TypeError

tp_hash : tp_richcompare tp_hash NULL tp_richcompare tp_hash

tp_richcompare PyObject_RichCompare() :

Py_LT <
Py_LE <=
Py_EQ ==
Py_NE !=
Py_GT >
Py_GE >=
Py_ssize_t PyTypeObject.tp_weaklistoffset

(GC ); PyObject_ClearWeakRefs() PyWeakref_*() NULL PyObject*

tp_weaklist ;

; tp_weaklistoffset

class __slots__ tp_weaklistoffset

__slots__ __weakref__ tp_weaklistoffset

__slots__ __weakref__ tp_weaklistoffset

getiterfunc PyTypeObject.tp_iter

()

PyObject_GetIter()

iternextfunc PyTypeObject.tp_iternext

NULL StopIteration NULL

tp_iter ()

PyIter_Next()

struct PyMethodDef* PyTypeObject.tp_methods

(regular) PyMethodDef NULL

( tp_dict )

()

struct PyMemberDef* PyTypeObject.tp_members

(regular) () PyMemberDef NULL

( tp_dict )

()

struct PyGetSetDef* PyTypeObject.tp_getset

(computed attribute) PyGetSetDef NULL

getter/setter ( tp_dict )

()

PyTypeObject* PyTypeObject.tp_base

(single inheritance) ;

() (Python object ) &PyBaseObject_Type

PyObject* PyTypeObject.tp_dict

PyType_Ready()

PyType_Ready() NULL ; PyType_Ready() (__add__() )

()

descrgetfunc PyTypeObject.tp_descr_get

get

PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);

descrsetfunc PyTypeObject.tp_descr_set

int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);

value NULL

Py_ssize_t PyTypeObject.tp_dictoffset

; PyObject_GenericGetAttr()

tp_dict ;

str tuple tp_basicsize 4 tp_dictoffset -4

tp_dictoffset :

dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset
if dictoffset is not aligned on sizeof(void*):
    round up to sizeof(void*)

tp_basicsize tp_itemsize tp_dictoffset ob_size ob_size (; _PyObject_GetDictPtr() )

; tp_dictoffset

class __slots__ tp_dictoffset

class __slots__ tp_dictoffset

(__dict__ __slots__ __weakref__ )

initproc PyTypeObject.tp_init

__init__() __init__() __init__() __init__()

int tp_init(PyObject *self, PyObject *args, PyObject *kwds)

self ; args kwds __init__()

tp_init NULL tp_new tp_new tp_init ; tp_new tp_init

allocfunc PyTypeObject.tp_alloc

PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)

ob_refcnt 1 ob_type (type argument) tp_itemsize ob_size nitems tp_basicsize + nitems*tp_itemsize sizeof(void*) ; nitems tp_basicsize

; tp_new

(class ) ; PyType_GenericAlloc() PyType_GenericAlloc()

newfunc PyTypeObject.tp_new

NULL ;

PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)

subtype ; args kwds tp_new ; ()

tp_new subtype->tp_alloc(subtype, nitems) tp_init tp_new tp_init

tp_base NULL &PyBaseObject_Type

destructor PyTypeObject.tp_free

freefunc :

void tp_free(void *)

PyObject_Free()

(class ) ; PyType_GenericAlloc() Py_TPFLAGS_HAVE_GC

inquiry PyTypeObject.tp_is_gc

tp_flags Py_TPFLAGS_HAVE_GC ; 1 0

int tp_is_gc(PyObject *self)

( PyType_Type )

PyObject* PyTypeObject.tp_bases

class NULL

PyObject* PyTypeObject.tp_mro

object (Method Resolution Order)

; PyType_Ready()

destructor PyTypeObject.tp_finalize

destructor :

void tp_finalize(PyObject *)

tp_finalize 1 ()

tp_finalize ; :

static void
local_finalize(PyObject *self)
{
    PyObject *error_type, *error_value, *error_traceback;

    /* Save the current exception, if any. */
    PyErr_Fetch(&error_type, &error_value, &error_traceback);

    /* ... */

    /* Restore the saved exception. */
    PyErr_Restore(error_type, error_value, error_traceback);
}

() Py_TPFLAGS_HAVE_FINALIZE

3.4 .

"" (PEP 442)

PyObject* PyTypeObject.tp_cache

PyObject* PyTypeObject.tp_subclasses

PyObject* PyTypeObject.tp_weaklist

COUNT_ALLOCS

Py_ssize_t PyTypeObject.tp_allocs

Py_ssize_t PyTypeObject.tp_frees

Py_ssize_t PyTypeObject.tp_maxalloc

PyTypeObject* PyTypeObject.tp_next

tp_allocs

Python tp_dealloc Python ()Python API tp_dealloc (GIL: Global Interpreter Lock) C C++ tp_dealloc

PyNumberMethods

(number protocol)

:

typedef struct {
     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;
     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;

(). Py_NotImplemented NULL

nb_reserved NULL nb_long Python 3.0.1

PyMappingMethods

3:

lenfunc PyMappingMethods.mp_length

This function is used by PyMapping_Length() and PyObject_Size(), and has the same signature. This slot may be set to NULL if the object has no defined length.

binaryfunc PyMappingMethods.mp_subscript

This function is used by PyObject_GetItem() and has the same signature. This slot must be filled for the PyMapping_Check() function to return 1, it can be NULL otherwise.

objobjargproc PyMappingMethods.mp_ass_subscript

This function is used by PyObject_SetItem() and PyObject_DelItem(). It has the same signature as PyObject_SetItem(), but v can also be set to NULL to delete an item. If this slot is NULL, the object does not support item assignment and deletion.

PySequenceMethods

lenfunc PySequenceMethods.sq_length

This function is used by PySequence_Size() and PyObject_Size(), and has the same signature.

binaryfunc PySequenceMethods.sq_concat

This function is used by PySequence_Concat() and has the same signature. It is also used by the + operator, after trying the numeric addition via the nb_add slot.

ssizeargfunc PySequenceMethods.sq_repeat

This function is used by PySequence_Repeat() and has the same signature. It is also used by the * operator, after trying numeric multiplication via the nb_multiply slot.

ssizeargfunc PySequenceMethods.sq_item

This function is used by PySequence_GetItem() and has the same signature. This slot must be filled for the PySequence_Check() function to return 1, it can be NULL otherwise.

: sq_length sq_item sq_length NULL

ssizeobjargproc PySequenceMethods.sq_ass_item

This function is used by PySequence_SetItem() and has the same signature. This slot may be left to NULL if the object does not support item assignment and deletion.

objobjproc PySequenceMethods.sq_contains

This function may be used by PySequence_Contains() and has the same signature. This slot may be left to NULL, in this case PySequence_Contains() simply traverses the sequence until it finds a match.

binaryfunc PySequenceMethods.sq_inplace_concat

This function is used by PySequence_InPlaceConcat() and has the same signature. It should modify its first operand, and return it.

ssizeargfunc PySequenceMethods.sq_inplace_repeat

This function is used by PySequence_InPlaceRepeat() and has the same signature. It should modify its first operand, and return it.

(buffer object structure)

PyBufferProcs

buffer

getbufferproc PyBufferProcs.bf_getbuffer

:

int (PyObject *exporter, Py_buffer *view, int flags);

flags view exporter (3) :

  1. PyExc_BufferError view->obj NULL -1
  2. view->obj exporter view->obj
  3. 0

exporter :

  • : view->obj
  • : view->obj

view

Py_buffer format shape strides suboffsets internal

PyBuffer_FillInfo()

PyObject_GetBuffer()

releasebufferproc PyBufferProcs.bf_releasebuffer

:

void (PyObject *exporter, Py_buffer *view);

PyBufferProcs.bf_releasebuffer NULL (optional step) :

  1. 0 view

internal view

view->obj PyBuffer_Release() ()

PyBuffer_Release()

async

3.5 .

PyAsyncMethods

awaitable asynchronous iterator

:

typedef struct {
    unaryfunc am_await;
    unaryfunc am_aiter;
    unaryfunc am_anext;
} PyAsyncMethods;
unaryfunc PyAsyncMethods.am_await

:

PyObject *am_await(PyObject *self)

PyIter_Check() 1

awaitable NULL

unaryfunc PyAsyncMethods.am_aiter

:

PyObject *am_aiter(PyObject *self)

awaitable __anext__()

NULL

unaryfunc PyAsyncMethods.am_anext

:

PyObject *am_anext(PyObject *self)

awaitable __anext__() NULL