blob: 8e27441bace00595a0c01565576c08e7a311acad [file] [log] [blame]
Guido van Rossume82f75a2001-10-18 20:47:51 +00001/* Implementation helper: a struct that looks like a tuple. See timemodule
2 and posixmodule for example uses. */
3
4#include "Python.h"
5#include "structmember.h"
6#include "structseq.h"
7
8static char visible_length_key[] = "n_sequence_fields";
9static char real_length_key[] = "n_fields";
Martin v. Löwisceaa77c2002-10-16 19:10:03 +000010static char unnamed_fields_key[] = "n_unnamed_fields";
Guido van Rossume82f75a2001-10-18 20:47:51 +000011
Martin v. Löwisf607bda2002-10-16 18:27:39 +000012/* Fields with this name have only a field index, not a field name.
13 They are only allowed for indices < n_visible_fields. */
14char *PyStructSequence_UnnamedField = "unnamed field";
15
Christian Heimese93237d2007-12-19 02:37:44 +000016#define VISIBLE_SIZE(op) Py_SIZE(op)
Guido van Rossume82f75a2001-10-18 20:47:51 +000017#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
18 PyDict_GetItemString((tp)->tp_dict, visible_length_key))
19
20#define REAL_SIZE_TP(tp) PyInt_AsLong( \
21 PyDict_GetItemString((tp)->tp_dict, real_length_key))
Christian Heimese93237d2007-12-19 02:37:44 +000022#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
Guido van Rossume82f75a2001-10-18 20:47:51 +000023
Martin v. Löwisceaa77c2002-10-16 19:10:03 +000024#define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
25 PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
Christian Heimese93237d2007-12-19 02:37:44 +000026#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
Martin v. Löwisceaa77c2002-10-16 19:10:03 +000027
Guido van Rossume82f75a2001-10-18 20:47:51 +000028
29PyObject *
30PyStructSequence_New(PyTypeObject *type)
31{
32 PyStructSequence *obj;
Christian Heimes620fbe62008-01-14 03:35:38 +000033
Neil Schemenauer7465ad22002-04-12 03:05:37 +000034 obj = PyObject_New(PyStructSequence, type);
Christian Heimese93237d2007-12-19 02:37:44 +000035 Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
Guido van Rossume82f75a2001-10-18 20:47:51 +000036
37 return (PyObject*) obj;
38}
39
40static void
41structseq_dealloc(PyStructSequence *obj)
42{
Martin v. Löwis18e16552006-02-15 17:27:45 +000043 Py_ssize_t i, size;
Guido van Rossume82f75a2001-10-18 20:47:51 +000044
45 size = REAL_SIZE(obj);
46 for (i = 0; i < size; ++i) {
47 Py_XDECREF(obj->ob_item[i]);
48 }
Neil Schemenauer7465ad22002-04-12 03:05:37 +000049 PyObject_Del(obj);
Guido van Rossume82f75a2001-10-18 20:47:51 +000050}
51
Martin v. Löwis18e16552006-02-15 17:27:45 +000052static Py_ssize_t
Guido van Rossume82f75a2001-10-18 20:47:51 +000053structseq_length(PyStructSequence *obj)
54{
55 return VISIBLE_SIZE(obj);
56}
57
58static PyObject*
Martin v. Löwis18e16552006-02-15 17:27:45 +000059structseq_item(PyStructSequence *obj, Py_ssize_t i)
Guido van Rossume82f75a2001-10-18 20:47:51 +000060{
61 if (i < 0 || i >= VISIBLE_SIZE(obj)) {
62 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
63 return NULL;
64 }
65 Py_INCREF(obj->ob_item[i]);
66 return obj->ob_item[i];
67}
68
69static PyObject*
Martin v. Löwis18e16552006-02-15 17:27:45 +000070structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
Guido van Rossume82f75a2001-10-18 20:47:51 +000071{
72 PyTupleObject *np;
Martin v. Löwis18e16552006-02-15 17:27:45 +000073 Py_ssize_t i;
Guido van Rossume82f75a2001-10-18 20:47:51 +000074
75 if (low < 0)
76 low = 0;
77 if (high > VISIBLE_SIZE(obj))
78 high = VISIBLE_SIZE(obj);
79 if (high < low)
80 high = low;
81 np = (PyTupleObject *)PyTuple_New(high-low);
82 if (np == NULL)
83 return NULL;
84 for(i = low; i < high; ++i) {
85 PyObject *v = obj->ob_item[i];
86 Py_INCREF(v);
Tim Petersc2fe6182001-10-30 23:20:46 +000087 PyTuple_SET_ITEM(np, i-low, v);
Guido van Rossume82f75a2001-10-18 20:47:51 +000088 }
89 return (PyObject *) np;
90}
91
92static PyObject *
Thomas Wouters3ccec682007-08-28 15:28:19 +000093structseq_subscript(PyStructSequence *self, PyObject *item)
94{
95 if (PyIndex_Check(item)) {
96 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
97 if (i == -1 && PyErr_Occurred())
98 return NULL;
99
100 if (i < 0)
101 i += VISIBLE_SIZE(self);
102
103 if (i < 0 || i >= VISIBLE_SIZE(self)) {
104 PyErr_SetString(PyExc_IndexError,
105 "tuple index out of range");
106 return NULL;
107 }
108 Py_INCREF(self->ob_item[i]);
109 return self->ob_item[i];
110 }
111 else if (PySlice_Check(item)) {
112 Py_ssize_t start, stop, step, slicelen, cur, i;
113 PyObject *result;
114
115 if (PySlice_GetIndicesEx((PySliceObject *)item,
116 VISIBLE_SIZE(self), &start, &stop,
117 &step, &slicelen) < 0) {
118 return NULL;
119 }
120 if (slicelen <= 0)
121 return PyTuple_New(0);
122 result = PyTuple_New(slicelen);
123 if (result == NULL)
124 return NULL;
125 for (cur = start, i = 0; i < slicelen;
126 cur += step, i++) {
127 PyObject *v = self->ob_item[cur];
128 Py_INCREF(v);
129 PyTuple_SET_ITEM(result, i, v);
130 }
131 return result;
132 }
133 else {
134 PyErr_SetString(PyExc_TypeError,
135 "structseq index must be integer");
136 return NULL;
137 }
138}
139
140static PyObject *
Guido van Rossume82f75a2001-10-18 20:47:51 +0000141structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
142{
143 PyObject *arg = NULL;
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000144 PyObject *dict = NULL;
145 PyObject *ob;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000146 PyStructSequence *res = NULL;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000147 Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
Martin v. Löwis15e62742006-02-27 16:46:16 +0000148 static char *kwlist[] = {"sequence", "dict", 0};
Guido van Rossume82f75a2001-10-18 20:47:51 +0000149
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000150 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
151 kwlist, &arg, &dict))
Guido van Rossume82f75a2001-10-18 20:47:51 +0000152 return NULL;
153
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000154 arg = PySequence_Fast(arg, "constructor requires a sequence");
155
156 if (!arg) {
Guido van Rossume82f75a2001-10-18 20:47:51 +0000157 return NULL;
158 }
159
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000160 if (dict && !PyDict_Check(dict)) {
161 PyErr_Format(PyExc_TypeError,
162 "%.500s() takes a dict as second arg, if any",
163 type->tp_name);
164 Py_DECREF(arg);
Guido van Rossume82f75a2001-10-18 20:47:51 +0000165 return NULL;
166 }
167
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000168 len = PySequence_Fast_GET_SIZE(arg);
169 min_len = VISIBLE_SIZE_TP(type);
170 max_len = REAL_SIZE_TP(type);
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000171 n_unnamed_fields = UNNAMED_FIELDS_TP(type);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000172
173 if (min_len != max_len) {
174 if (len < min_len) {
175 PyErr_Format(PyExc_TypeError,
Martin v. Löwis2c95cc62006-02-16 06:54:25 +0000176 "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
Martin v. Löwise0e89f72006-02-16 06:59:22 +0000177 type->tp_name, min_len, len);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000178 Py_DECREF(arg);
179 return NULL;
180 }
181
182 if (len > max_len) {
183 PyErr_Format(PyExc_TypeError,
Martin v. Löwis2c95cc62006-02-16 06:54:25 +0000184 "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
Martin v. Löwise0e89f72006-02-16 06:59:22 +0000185 type->tp_name, max_len, len);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000186 Py_DECREF(arg);
187 return NULL;
188 }
189 }
190 else {
191 if (len != min_len) {
192 PyErr_Format(PyExc_TypeError,
Martin v. Löwis2c95cc62006-02-16 06:54:25 +0000193 "%.500s() takes a %zd-sequence (%zd-sequence given)",
Martin v. Löwise0e89f72006-02-16 06:59:22 +0000194 type->tp_name, min_len, len);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000195 Py_DECREF(arg);
196 return NULL;
197 }
198 }
199
Guido van Rossume82f75a2001-10-18 20:47:51 +0000200 res = (PyStructSequence*) PyStructSequence_New(type);
Neal Norwitz8feeabb2002-12-18 23:20:39 +0000201 if (res == NULL) {
202 return NULL;
203 }
Guido van Rossume82f75a2001-10-18 20:47:51 +0000204 for (i = 0; i < len; ++i) {
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000205 PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
206 Py_INCREF(v);
207 res->ob_item[i] = v;
208 }
209 for (; i < max_len; ++i) {
210 if (dict && (ob = PyDict_GetItemString(
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000211 dict, type->tp_members[i-n_unnamed_fields].name))) {
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000212 }
213 else {
214 ob = Py_None;
215 }
216 Py_INCREF(ob);
217 res->ob_item[i] = ob;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000218 }
219
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000220 Py_DECREF(arg);
Guido van Rossume82f75a2001-10-18 20:47:51 +0000221 return (PyObject*) res;
222}
223
224static PyObject *
225make_tuple(PyStructSequence *obj)
226{
227 return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
228}
229
230static PyObject *
231structseq_repr(PyStructSequence *obj)
232{
Christian Heimes620fbe62008-01-14 03:35:38 +0000233 PyObject *tup, *val, *repr;
234 PyTypeObject *typ = Py_TYPE(obj);
235 int i, len;
236 char buf[250+5]; /* "...)\0" */
237 char *cname, *crepr;
238 char *pbuf = buf;
239 char *endbuf = &buf[250];
240
241 strncpy(pbuf, typ->tp_name, 50);
242 pbuf += strlen(typ->tp_name) > 50 ? 50 : strlen(typ->tp_name);
243 *pbuf++ = '(';
244
245 if ((tup = make_tuple(obj)) == NULL) {
246 return NULL;
247 }
248 for (i=0; i < VISIBLE_SIZE(obj); i++) {
249 cname = typ->tp_members[i].name;
250 val = PyTuple_GetItem(tup, i);
251 if (cname == NULL || val == NULL) {
252 return NULL;
253 }
254 repr = PyObject_Repr(val);
255 if (repr == NULL) {
256 Py_DECREF(tup);
257 return NULL;
258 }
259 crepr = PyString_AsString(repr);
260 if (crepr == NULL) {
261 Py_DECREF(tup);
262 Py_DECREF(repr);
263 return NULL;
264 }
265 len = strlen(cname) + strlen(crepr) + 3;
266 if ((pbuf+len) < endbuf) {
267 strcpy(pbuf, cname);
268 pbuf += strlen(cname);
269 *pbuf++ = '=';
270 strcpy(pbuf, crepr);
271 pbuf += strlen(crepr);
272 *pbuf++ = ',';
273 *pbuf++ = ' ';
274 Py_DECREF(repr);
275 }
276 else {
277 strcpy(pbuf, "...");
278 pbuf += 5;
279 Py_DECREF(repr);
280 break;
281 }
282 }
Guido van Rossume82f75a2001-10-18 20:47:51 +0000283 Py_DECREF(tup);
Christian Heimes620fbe62008-01-14 03:35:38 +0000284
285 pbuf-=2;
286 *pbuf++ = ')';
287 *pbuf = '\0';
288
289 repr = PyString_FromString(buf);
290 return repr;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000291}
292
293static PyObject *
294structseq_concat(PyStructSequence *obj, PyObject *b)
295{
296 PyObject *tup, *result;
297 tup = make_tuple(obj);
298 result = PySequence_Concat(tup, b);
299 Py_DECREF(tup);
300 return result;
301}
302
303static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000304structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000305{
306 PyObject *tup, *result;
307 tup = make_tuple(obj);
308 result = PySequence_Repeat(tup, n);
309 Py_DECREF(tup);
310 return result;
311}
312
313static int
314structseq_contains(PyStructSequence *obj, PyObject *o)
315{
316 PyObject *tup;
317 int result;
318 tup = make_tuple(obj);
Neal Norwitz6f5ff3f2006-08-12 01:43:40 +0000319 if (!tup)
320 return -1;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000321 result = PySequence_Contains(tup, o);
322 Py_DECREF(tup);
323 return result;
324}
325
326static long
327structseq_hash(PyObject *obj)
328{
329 PyObject *tup;
330 long result;
331 tup = make_tuple((PyStructSequence*) obj);
Neal Norwitz6f5ff3f2006-08-12 01:43:40 +0000332 if (!tup)
333 return -1;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000334 result = PyObject_Hash(tup);
335 Py_DECREF(tup);
336 return result;
337}
338
339static PyObject *
340structseq_richcompare(PyObject *obj, PyObject *o2, int op)
341{
342 PyObject *tup, *result;
343 tup = make_tuple((PyStructSequence*) obj);
344 result = PyObject_RichCompare(tup, o2, op);
345 Py_DECREF(tup);
346 return result;
347}
348
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000349static PyObject *
350structseq_reduce(PyStructSequence* self)
351{
352 PyObject* tup;
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000353 PyObject* dict;
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000354 PyObject* result;
Martin v. Löwiseb079f12006-02-16 14:32:27 +0000355 Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000356 int i;
357
358 n_fields = REAL_SIZE(self);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000359 n_visible_fields = VISIBLE_SIZE(self);
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000360 n_unnamed_fields = UNNAMED_FIELDS(self);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000361 tup = PyTuple_New(n_visible_fields);
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000362 if (!tup) {
363 return NULL;
364 }
365
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000366 dict = PyDict_New();
367 if (!dict) {
368 Py_DECREF(tup);
369 return NULL;
370 }
371
372 for (i = 0; i < n_visible_fields; i++) {
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000373 Py_INCREF(self->ob_item[i]);
374 PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
375 }
376
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000377 for (; i < n_fields; i++) {
Christian Heimese93237d2007-12-19 02:37:44 +0000378 char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000379 PyDict_SetItemString(dict, n,
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000380 self->ob_item[i]);
381 }
382
Christian Heimese93237d2007-12-19 02:37:44 +0000383 result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000384
385 Py_DECREF(tup);
386 Py_DECREF(dict);
387
388 return result;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000389}
390
Guido van Rossume82f75a2001-10-18 20:47:51 +0000391static PySequenceMethods structseq_as_sequence = {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000392 (lenfunc)structseq_length,
Guido van Rossume82f75a2001-10-18 20:47:51 +0000393 (binaryfunc)structseq_concat, /* sq_concat */
Martin v. Löwis18e16552006-02-15 17:27:45 +0000394 (ssizeargfunc)structseq_repeat, /* sq_repeat */
395 (ssizeargfunc)structseq_item, /* sq_item */
396 (ssizessizeargfunc)structseq_slice, /* sq_slice */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000397 0, /* sq_ass_item */
398 0, /* sq_ass_slice */
399 (objobjproc)structseq_contains, /* sq_contains */
400};
401
Thomas Wouters3ccec682007-08-28 15:28:19 +0000402static PyMappingMethods structseq_as_mapping = {
403 (lenfunc)structseq_length,
404 (binaryfunc)structseq_subscript,
405};
406
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000407static PyMethodDef structseq_methods[] = {
408 {"__reduce__", (PyCFunction)structseq_reduce,
409 METH_NOARGS, NULL},
410 {NULL, NULL}
411};
412
Guido van Rossume82f75a2001-10-18 20:47:51 +0000413static PyTypeObject _struct_sequence_template = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000414 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000415 NULL, /* tp_name */
416 0, /* tp_basicsize */
417 0, /* tp_itemsize */
418 (destructor)structseq_dealloc, /* tp_dealloc */
419 0, /* tp_print */
420 0, /* tp_getattr */
421 0, /* tp_setattr */
422 0, /* tp_compare */
423 (reprfunc)structseq_repr, /* tp_repr */
424 0, /* tp_as_number */
425 &structseq_as_sequence, /* tp_as_sequence */
Thomas Wouters3ccec682007-08-28 15:28:19 +0000426 &structseq_as_mapping, /* tp_as_mapping */
Georg Brandl347b3002006-03-30 11:57:00 +0000427 structseq_hash, /* tp_hash */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000428 0, /* tp_call */
429 0, /* tp_str */
430 0, /* tp_getattro */
431 0, /* tp_setattro */
432 0, /* tp_as_buffer */
433 Py_TPFLAGS_DEFAULT, /* tp_flags */
434 NULL, /* tp_doc */
435 0, /* tp_traverse */
436 0, /* tp_clear */
437 structseq_richcompare, /* tp_richcompare */
438 0, /* tp_weaklistoffset */
439 0, /* tp_iter */
440 0, /* tp_iternext */
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000441 structseq_methods, /* tp_methods */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000442 NULL, /* tp_members */
443 0, /* tp_getset */
444 0, /* tp_base */
445 0, /* tp_dict */
446 0, /* tp_descr_get */
447 0, /* tp_descr_set */
448 0, /* tp_dictoffset */
449 0, /* tp_init */
450 0, /* tp_alloc */
451 structseq_new, /* tp_new */
452};
453
454void
455PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
456{
457 PyObject *dict;
458 PyMemberDef* members;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000459 int n_members, n_unnamed_members, i, k;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000460
Martin v. Löwisc597d1b2006-04-15 12:45:05 +0000461#ifdef Py_TRACE_REFS
462 /* if the type object was chained, unchain it first
463 before overwriting its storage */
464 if (type->_ob_next) {
465 _Py_ForgetReference((PyObject*)type);
466 }
467#endif
468
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000469 n_unnamed_members = 0;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000470 for (i = 0; desc->fields[i].name != NULL; ++i)
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000471 if (desc->fields[i].name == PyStructSequence_UnnamedField)
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000472 n_unnamed_members++;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000473 n_members = i;
474
475 memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
476 type->tp_name = desc->name;
477 type->tp_doc = desc->doc;
478 type->tp_basicsize = sizeof(PyStructSequence)+
479 sizeof(PyObject*)*(n_members-1);
480 type->tp_itemsize = 0;
481
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000482 members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
Neal Norwitz8feeabb2002-12-18 23:20:39 +0000483 if (members == NULL)
484 return;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000485
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000486 for (i = k = 0; i < n_members; ++i) {
487 if (desc->fields[i].name == PyStructSequence_UnnamedField)
488 continue;
489 members[k].name = desc->fields[i].name;
490 members[k].type = T_OBJECT;
491 members[k].offset = offsetof(PyStructSequence, ob_item)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000492 + i * sizeof(PyObject*);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000493 members[k].flags = READONLY;
494 members[k].doc = desc->fields[i].doc;
495 k++;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000496 }
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000497 members[k].name = NULL;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000498
499 type->tp_members = members;
500
501 if (PyType_Ready(type) < 0)
502 return;
503 Py_INCREF(type);
504
505 dict = type->tp_dict;
506 PyDict_SetItemString(dict, visible_length_key,
507 PyInt_FromLong((long) desc->n_in_sequence));
508 PyDict_SetItemString(dict, real_length_key,
509 PyInt_FromLong((long) n_members));
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000510 PyDict_SetItemString(dict, unnamed_fields_key,
511 PyInt_FromLong((long) n_unnamed_members));
Guido van Rossume82f75a2001-10-18 20:47:51 +0000512}