CPython C-API: tp_alloc, tp_new, and tp_init Explained

Creating custom extension types in the CPython C-API requires managing how instances are allocated in memory, constructed, and initialized. When a Python class is instantiated, CPython delegates these responsibilities across three dedicated slots in the PyTypeObject struct: tp_alloc, tp_new, and tp_init. This article explains the exact purpose of each slot, how they interact, and their roles in the object creation lifecycle.


The Object Lifecycle Overview

When code calls a type like obj = MyType(arg1, key=val), CPython's default type call handler (type_call) executes a three-phase sequence:

  1. tp_new is invoked to construct and return an instance of the class.
  2. Inside tp_new, tp_alloc is typically called to reserve heap memory for that instance.
  3. If tp_new successfully returns an instance of MyType (or a subclass), CPython automatically calls tp_init to initialize the instance's state.

1. tp_alloc: Memory Allocation

PyObject* (*allocfunc)(PyTypeObject *type, Py_ssize_t nitems);

Purpose

tp_alloc handles the low-level allocation of raw memory required to store an instance of the type.

Responsibilities

Usage

Most custom extension types do not need to implement their own tp_alloc. Instead, they inherit or explicitly set PyType_GenericAlloc. Custom implementations are only necessary if an extension requires specialized memory pools, arena allocators, or unique alignment constraints.


2. tp_new: Instance Construction

PyObject* (*newfunc)(PyTypeObject *subtype, PyObject *args, PyObject *kwds);

Purpose

tp_new represents the constructor of the class and corresponds directly to Python's __new__() method. Its primary role is to produce and return an instance of the type.

Responsibilities

Return Value


3. tp_init: Instance Initialization

int (*initproc)(PyObject *self, PyObject *args, PyObject *kwds);

Purpose

tp_init represents the initializer of the class and corresponds directly to Python's __init__() method. It receives the already-allocated instance and configures its mutable state.

Responsibilities

Return Value


Summary of Differences

Feature tp_alloc tp_new tp_init
Python Equivalent None (internal) __new__() __init__()
Primary Goal Reserve memory block Create/return object Configure object state
Receives Type pointer, item count Type pointer, args, kwargs Instantiated object, args, kwargs
Returns Raw PyObject* Constructed PyObject* int (0 or -1)
Standard Handler PyType_GenericAlloc Custom C function Custom C function