/Doc/includes/noddy3.c

http://unladen-swallow.googlecode.com/ · C · 243 lines · 205 code · 38 blank · 0 comment · 24 complexity · ea2affacd1a3ad58a408a32300946c4a MD5 · raw file

  1. #include <Python.h>
  2. #include "structmember.h"
  3. typedef struct {
  4. PyObject_HEAD
  5. PyObject *first;
  6. PyObject *last;
  7. int number;
  8. } Noddy;
  9. static void
  10. Noddy_dealloc(Noddy* self)
  11. {
  12. Py_XDECREF(self->first);
  13. Py_XDECREF(self->last);
  14. self->ob_type->tp_free((PyObject*)self);
  15. }
  16. static PyObject *
  17. Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  18. {
  19. Noddy *self;
  20. self = (Noddy *)type->tp_alloc(type, 0);
  21. if (self != NULL) {
  22. self->first = PyString_FromString("");
  23. if (self->first == NULL)
  24. {
  25. Py_DECREF(self);
  26. return NULL;
  27. }
  28. self->last = PyString_FromString("");
  29. if (self->last == NULL)
  30. {
  31. Py_DECREF(self);
  32. return NULL;
  33. }
  34. self->number = 0;
  35. }
  36. return (PyObject *)self;
  37. }
  38. static int
  39. Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
  40. {
  41. PyObject *first=NULL, *last=NULL, *tmp;
  42. static char *kwlist[] = {"first", "last", "number", NULL};
  43. if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
  44. &first, &last,
  45. &self->number))
  46. return -1;
  47. if (first) {
  48. tmp = self->first;
  49. Py_INCREF(first);
  50. self->first = first;
  51. Py_DECREF(tmp);
  52. }
  53. if (last) {
  54. tmp = self->last;
  55. Py_INCREF(last);
  56. self->last = last;
  57. Py_DECREF(tmp);
  58. }
  59. return 0;
  60. }
  61. static PyMemberDef Noddy_members[] = {
  62. {"number", T_INT, offsetof(Noddy, number), 0,
  63. "noddy number"},
  64. {NULL} /* Sentinel */
  65. };
  66. static PyObject *
  67. Noddy_getfirst(Noddy *self, void *closure)
  68. {
  69. Py_INCREF(self->first);
  70. return self->first;
  71. }
  72. static int
  73. Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
  74. {
  75. if (value == NULL) {
  76. PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
  77. return -1;
  78. }
  79. if (! PyString_Check(value)) {
  80. PyErr_SetString(PyExc_TypeError,
  81. "The first attribute value must be a string");
  82. return -1;
  83. }
  84. Py_DECREF(self->first);
  85. Py_INCREF(value);
  86. self->first = value;
  87. return 0;
  88. }
  89. static PyObject *
  90. Noddy_getlast(Noddy *self, void *closure)
  91. {
  92. Py_INCREF(self->last);
  93. return self->last;
  94. }
  95. static int
  96. Noddy_setlast(Noddy *self, PyObject *value, void *closure)
  97. {
  98. if (value == NULL) {
  99. PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
  100. return -1;
  101. }
  102. if (! PyString_Check(value)) {
  103. PyErr_SetString(PyExc_TypeError,
  104. "The last attribute value must be a string");
  105. return -1;
  106. }
  107. Py_DECREF(self->last);
  108. Py_INCREF(value);
  109. self->last = value;
  110. return 0;
  111. }
  112. static PyGetSetDef Noddy_getseters[] = {
  113. {"first",
  114. (getter)Noddy_getfirst, (setter)Noddy_setfirst,
  115. "first name",
  116. NULL},
  117. {"last",
  118. (getter)Noddy_getlast, (setter)Noddy_setlast,
  119. "last name",
  120. NULL},
  121. {NULL} /* Sentinel */
  122. };
  123. static PyObject *
  124. Noddy_name(Noddy* self)
  125. {
  126. static PyObject *format = NULL;
  127. PyObject *args, *result;
  128. if (format == NULL) {
  129. format = PyString_FromString("%s %s");
  130. if (format == NULL)
  131. return NULL;
  132. }
  133. args = Py_BuildValue("OO", self->first, self->last);
  134. if (args == NULL)
  135. return NULL;
  136. result = PyString_Format(format, args);
  137. Py_DECREF(args);
  138. return result;
  139. }
  140. static PyMethodDef Noddy_methods[] = {
  141. {"name", (PyCFunction)Noddy_name, METH_NOARGS,
  142. "Return the name, combining the first and last name"
  143. },
  144. {NULL} /* Sentinel */
  145. };
  146. static PyTypeObject NoddyType = {
  147. PyObject_HEAD_INIT(NULL)
  148. 0, /*ob_size*/
  149. "noddy.Noddy", /*tp_name*/
  150. sizeof(Noddy), /*tp_basicsize*/
  151. 0, /*tp_itemsize*/
  152. (destructor)Noddy_dealloc, /*tp_dealloc*/
  153. 0, /*tp_print*/
  154. 0, /*tp_getattr*/
  155. 0, /*tp_setattr*/
  156. 0, /*tp_compare*/
  157. 0, /*tp_repr*/
  158. 0, /*tp_as_number*/
  159. 0, /*tp_as_sequence*/
  160. 0, /*tp_as_mapping*/
  161. 0, /*tp_hash */
  162. 0, /*tp_call*/
  163. 0, /*tp_str*/
  164. 0, /*tp_getattro*/
  165. 0, /*tp_setattro*/
  166. 0, /*tp_as_buffer*/
  167. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  168. "Noddy objects", /* tp_doc */
  169. 0, /* tp_traverse */
  170. 0, /* tp_clear */
  171. 0, /* tp_richcompare */
  172. 0, /* tp_weaklistoffset */
  173. 0, /* tp_iter */
  174. 0, /* tp_iternext */
  175. Noddy_methods, /* tp_methods */
  176. Noddy_members, /* tp_members */
  177. Noddy_getseters, /* tp_getset */
  178. 0, /* tp_base */
  179. 0, /* tp_dict */
  180. 0, /* tp_descr_get */
  181. 0, /* tp_descr_set */
  182. 0, /* tp_dictoffset */
  183. (initproc)Noddy_init, /* tp_init */
  184. 0, /* tp_alloc */
  185. Noddy_new, /* tp_new */
  186. };
  187. static PyMethodDef module_methods[] = {
  188. {NULL} /* Sentinel */
  189. };
  190. #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
  191. #define PyMODINIT_FUNC void
  192. #endif
  193. PyMODINIT_FUNC
  194. initnoddy3(void)
  195. {
  196. PyObject* m;
  197. if (PyType_Ready(&NoddyType) < 0)
  198. return;
  199. m = Py_InitModule3("noddy3", module_methods,
  200. "Example module that creates an extension type.");
  201. if (m == NULL)
  202. return;
  203. Py_INCREF(&NoddyType);
  204. PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
  205. }