Extending and Embedding Python, Release 3.9.5 (continued from previous page) (continues on next page) Chapter 2. Creating extensions without third party tools 40 static int Custom_setfirst(CustomObject *self, PyObject*value, void *closure) { if (value==NULL ) { PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute "); return -1 ; } if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "The first attribute value must be a string "); return -1 ; } Py_INCREF(value); Py_CLEAR(self->first); self->first =value; return 0; } static PyObject * Custom_getlast(CustomObject *self, void *closure) { Py_INCREF(self->last); return self->last; } static int Custom_setlast(CustomObject *self, PyObject*value, void *closure) { if (value==NULL ) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute "); return -1 ; } if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "The last attribute value must be a string "); return -1 ; } Py_INCREF(value); Py_CLEAR(self->last); self->last=value; return 0; } 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 */ }; static PyObject * Custom_name(CustomObject *self, PyObject*Py_UNUSED(ignored)) { return PyUnicode_FromFormat("%S %S ", self ->first, self ->last); } static PyMethodDef Custom_methods[] ={ { "name", (PyCFunction) Custom_name, METH_NOARGS, "Return the name, combining the first and last name " },