Extending and Embedding Python, Release 3.9.5 29 2.2. Defining Extension Types: Tutorial (continues on next page) #include<structmember.h> This include provides declarations that we use to handle attributes, as described a bit later. The$_{Custom}$type now has three data attributes in its C struct, first , last , and number . The first and last variables are Python strings containing first and last names. The number attribute is a C integer. The object structure is updated accordingly: Because we now have data to manage, we have to be more careful about object allocation and deallocation. At a minimum, we need a deallocation method: which is assigned to the$_{tp_dealloc}$ member: .tp_dealloc =(destructor) Custom_dealloc, This method first clears the reference counts of the two Python attributes. Py_XDECREF() correctly handles the case where its argument is$_{NULL}$ (which might happen here if$_{tp_new}$ failed midway). It then calls the$_{tp_free}$ member of the object’s type (computed by$_{Py_TYPE(self)}$ ) to free the object’s memory. Note that the object’s type might not be$_{CustomType}$, because the object may be an instance of a subclass. Note: The explicit cast to $_{destructor}$above is needed because we defined Custom_dealloc to take a CustomObject * argument, but the$_{tp_dealloc}$ function pointer expects to receive a$_{PyObject *}$ argu- ment. Otherwise, the compiler will emit a warning. This is object-oriented polymorphism, in C! We want to make sure that the first and last names are initialized to empty strings, so we provide a$_{tp_new}$ imple- mentation: static PyObject * Custom_new(PyTypeObject *type, PyObject*args, PyObject*kwds) { CustomObject*self; self =(CustomObject*) type->tp_alloc(type, 0); if (self!=NULL ) { self->first =PyUnicode_FromString(""); if (self ->first ==NULL ) { Py_DECREF(self); return NULL ; } self->last=PyUnicode_FromString(""); if (self ->last==NULL ) { Py_DECREF(self); return NULL ; } self->number =0; static void Custom_dealloc(CustomObject *self) { Py_XDECREF(self ->first); Py_XDECREF(self ->last); Py_TYPE(self) ->tp_free((PyObject *) self); } typedef struct { PyObject_HEAD PyObject *first; /* first name */ PyObject *last; /* last name */ int number; } CustomObject;