#include #include typedef struct { PyObject_HEAD PyObject *firstname; PyObject *lastname; } NameObject; static int Name_init(NameObject *self, PyObject *args, PyObject *kwds) { PyObject *firstname = Py_None; PyObject *lastname = Py_None; PyObject *tmp = NULL; static char *kwlist[] = {"firstname", "lastname", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, &firstname, &lastname)) return -1; tmp = self->firstname; if (firstname == Py_None) { self->firstname = PyString_FromString(""); } else { Py_INCREF(firstname); self->firstname = firstname; } Py_XDECREF(tmp); tmp = self->lastname; if (lastname == Py_None) { self->lastname = PyString_FromString(""); } else { Py_INCREF(lastname); self->lastname = lastname; } Py_XDECREF(tmp); return 0; } static PyMemberDef Name_members[] = { {"firstname", T_OBJECT_EX, offsetof(NameObject, firstname), 0, "first name"}, {"lastname", T_OBJECT_EX, offsetof(NameObject, lastname), 0, "last name"}, {NULL} /* Sentinel */ }; static PyObject * Name_name(NameObject *self, PyObject *unused) { PyObject *args = NULL; PyObject *format = NULL; PyObject *result = NULL; format = PyString_FromString("%s %s"); if (format == NULL) goto fail; if (self->firstname == NULL) { PyErr_SetString(PyExc_AttributeError, "firstname"); goto fail; } if (self->lastname == NULL) { PyErr_SetString(PyExc_AttributeError, "lastname"); goto fail; } args = Py_BuildValue("OO", self->firstname, self->lastname); if (args == NULL) goto fail; result = PyString_Format(format, args); fail: Py_XDECREF(format); Py_XDECREF(args); return result; } static PyMethodDef Name_methods[] = { {"name", (PyCFunction)Name_name, METH_NOARGS, "Return the name, combining the firstname and lastname." }, {NULL} }; static char Name_doc[] = "boo."; static PyTypeObject NameObjectType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "name.Name", /* tp_name */ sizeof(NameObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ Name_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ Name_methods, /* tp_methods */ Name_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)Name_init, /* tp_init */ }; PyMODINIT_FUNC initname(void) { PyObject* m; NameObjectType.tp_new = PyType_GenericNew; if (PyType_Ready(&NameObjectType) < 0) return; m = Py_InitModule3("name", NULL, "XXX"); if (m == NULL) return; Py_INCREF(&NameObjectType); PyModule_AddObject(m, "Name", (PyObject *)&NameObjectType); }