Py_INCREF(last); self->last=last; Py_XDECREF(tmp); } return 0; } 

by filling the tp_init slot. 

.tp_init=(initproc) Custom_init, 

(continued from previous page) 

The$_{tp_init}$slot is exposed in Python as the$_{__init__()}$ method. It is used to initialize an object after it’s created. Initializers always accept positional and keyword arguments, and they should return either$_{0}$on success or -1 on error. 

Unlike the$_{tp_new}$ handler, there is no guarantee that$_{tp_init}$is called at all (for example, the$_{pickle}$module by default doesn’t call __init__() on unpickled instances). It can also be called multiple times. Anyone can call the __init__() method on our objects. For this reason, we have to be extra careful when assigning the new attribute values. We might be tempted, for example to assign the$_{first}$ member like this: 

if (first) { Py_XDECREF(self ->first); Py_INCREF(first); self->first =first; } 

But this would be risky. Our type doesn’t restrict the type of the$_{first}$ member, so it could be any kind of object. It could have a destructor that causes code to be executed that tries to access the$_{first}$ member; or that destructor could release the Global interpreter Lock and let arbitrary code run in other threads that accesses and modifies our object. 

To be paranoid and protect ourselves against this possibility, we almost always reassign members before decrementing their reference counts. When don’t we have to do this? 

• when we absolutely know that the reference count is greater than 1; 

• when we know that deallocation of the object 1 will neither release the GIL nor cause any calls back into our type’s code; 

• when decrementing a reference count in a tp_dealloc handler on a type which doesn’t support cyclic garbage collection$^{2}$. 

We want to expose our instance variables as attributes. There are a number of ways to do that. The simplest way is to define member definitions: 

static PyMemberDef Custom_members[]={ { "first", T_OBJECT_EX, offsetof(CustomObject, first), 0, "first name"}, { "last", T_OBJECT_EX, offsetof(CustomObject, last), 0, "last name "}, { "number", T_INT, offsetof(CustomObject, number), 0, "custom number "}, { NULL } /* Sentinel */ }; 

and put the definitions in the$_{tp_members}$ slot: 

.tp_members=Custom_members, 

