static PyGetSetDef Custom_getsetters[]={ { "first", (getter) Custom_getfirst, (setter) Custom_setfirst, "first name",NULL }, { "last", (getter) Custom_getlast, (setter) Custom_setlast, "last name ",NULL }, { NULL } /* Sentinel */ }; 

and register it in the tp_getset slot: 

.tp_getset =Custom_getsetters, 

The last item in a$_{PyGetSetDef}$ structure is the “closure” mentioned above. In this case, we aren’t using a closure, so we just pass NULL . 

We also remove the member definitions for these attributes: 

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

We also need to update the$_{tp_init}$handler to only allow strings 3 to be passed: 

static int Custom_init(CustomObject *self, PyObject*args, PyObject*kwds) { static char *kwlist[] ={ "first","last","number",NULL }; PyObject *first =NULL ,*last=NULL ,*tmp; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi ", kwlist, &first,&last, &self->number)) return -1 ; if (first) { tmp =self->first; Py_INCREF(first); self->first =first; Py_DECREF(tmp); } if (last) { tmp =self->last; Py_INCREF(last); self->last=last; Py_DECREF(tmp); } return 0; } 

With these changes, we can assure that the$_{first}$ and$_{last}$members are never$_{NULL}$ so we can remove checks for NULL values in almost all cases. This means that most of the Py_XDECREF() calls can be converted to Py_DECREF() calls. The only place we can’t change these calls is in the$_{tp_dealloc}$ implementation, where there is the possibility that the initialization of these members failed in$_{tp_new}$ . 

We also rename the module initialization function and module name in the initialization function, as we did before, and we add an extra definition to the$_{setup.py}$ file. 

