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