Extending and Embedding Python, Release 3.9.5 (continued from previous page) (continues on next page) 2.2. Defining Extension Types: Tutorial 35 { PyObject *tmp; 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 ; } tmp =self->last; Py_INCREF(value); self->last=value; Py_DECREF(tmp); 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 " }, { NULL } /* Sentinel */ }; static PyTypeObject CustomType={ PyVarObject_HEAD_INIT(NULL ,0) .tp_name ="custom3.Custom ", .tp_doc="Custom objects", .tp_basicsize= sizeof (CustomObject), .tp_itemsize=0, .tp_flags =Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_new=Custom_new, .tp_init=(initproc) Custom_init, .tp_dealloc =(destructor) Custom_dealloc, .tp_members=Custom_members, .tp_methods=Custom_methods, .tp_getset =Custom_getsetters, }; static PyModuleDef custommodule={ PyModuleDef_HEAD_INIT, .m_name="custom3 ", .m_doc="Example module that creates an extension type. ", .m_size=-1 , };