blob: 56e885c8c323693d501974c26a67b67b50711841 [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 Heimes90aa7642007-12-19 02:45:37 +000016#define VISIBLE_SIZE(op) Py_SIZE(op)
Christian Heimes217cfd12007-12-02 14:31:20 +000017#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
Guido van Rossume82f75a2001-10-18 20:47:51 +000018 PyDict_GetItemString((tp)->tp_dict, visible_length_key))
19
Christian Heimes217cfd12007-12-02 14:31:20 +000020#define REAL_SIZE_TP(tp) PyLong_AsLong( \
Guido van Rossume82f75a2001-10-18 20:47:51 +000021 PyDict_GetItemString((tp)->tp_dict, real_length_key))
Christian Heimes90aa7642007-12-19 02:45:37 +000022#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
Guido van Rossume82f75a2001-10-18 20:47:51 +000023
Christian Heimes217cfd12007-12-02 14:31:20 +000024#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
Martin v. Löwisceaa77c2002-10-16 19:10:03 +000025 PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
Christian Heimes90aa7642007-12-19 02:45:37 +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 Heimesd32ed6f2008-01-14 18:49:24 +000033
Neil Schemenauer7465ad22002-04-12 03:05:37 +000034 obj = PyObject_New(PyStructSequence, type);
Christian Heimes90aa7642007-12-19 02:45:37 +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 Woutersed03b412007-08-28 21:37:11 +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 Heimesd32ed6f2008-01-14 18:49:24 +0000233 /* buffer and type size were chosen well considered. */
234#define REPR_BUFFER_SIZE 512
235#define TYPE_MAXSIZE 100
236
237 PyObject *tup;
238 PyTypeObject *typ = Py_TYPE(obj);
239 int i, removelast = 0;
240 Py_ssize_t len;
241 char buf[REPR_BUFFER_SIZE];
242 char *endofbuf, *pbuf = buf;
243
244 /* pointer to end of writeable buffer; safes space for "...)\0" */
245 endofbuf= &buf[REPR_BUFFER_SIZE-5];
246
247 if ((tup = make_tuple(obj)) == NULL) {
248 return NULL;
249 }
250
251 /* "typename(", limited to TYPE_MAXSIZE */
252 len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
253 strlen(typ->tp_name);
254 strncpy(pbuf, typ->tp_name, len);
255 pbuf += len;
256 *pbuf++ = '(';
257
258 for (i=0; i < VISIBLE_SIZE(obj); i++) {
259 PyObject *val, *repr;
260 char *cname, *crepr;
261
262 cname = typ->tp_members[i].name;
263
264 val = PyTuple_GetItem(tup, i);
265 if (cname == NULL || val == NULL) {
266 return NULL;
267 }
268 repr = PyObject_Repr(val);
269 if (repr == NULL) {
270 Py_DECREF(tup);
271 return NULL;
272 }
273 crepr = PyUnicode_AsString(repr);
274 if (crepr == NULL) {
275 Py_DECREF(tup);
276 Py_DECREF(repr);
277 return NULL;
278 }
279
280 /* + 3: keep space for "=" and ", " */
281 len = strlen(cname) + strlen(crepr) + 3;
282 if ((pbuf+len) <= endofbuf) {
283 strcpy(pbuf, cname);
284 pbuf += strlen(cname);
285 *pbuf++ = '=';
286 strcpy(pbuf, crepr);
287 pbuf += strlen(crepr);
288 *pbuf++ = ',';
289 *pbuf++ = ' ';
290 removelast = 1;
291 Py_DECREF(repr);
292 }
293 else {
294 strcpy(pbuf, "...");
295 pbuf += 3;
296 removelast = 0;
297 Py_DECREF(repr);
298 break;
299 }
300 }
Guido van Rossume82f75a2001-10-18 20:47:51 +0000301 Py_DECREF(tup);
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000302 if (removelast) {
303 /* overwrite last ", " */
304 pbuf-=2;
305 }
306 *pbuf++ = ')';
307 *pbuf = '\0';
308
309 return PyUnicode_FromString(buf);
Guido van Rossume82f75a2001-10-18 20:47:51 +0000310}
311
312static PyObject *
313structseq_concat(PyStructSequence *obj, PyObject *b)
314{
315 PyObject *tup, *result;
316 tup = make_tuple(obj);
317 result = PySequence_Concat(tup, b);
318 Py_DECREF(tup);
319 return result;
320}
321
322static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000323structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000324{
325 PyObject *tup, *result;
326 tup = make_tuple(obj);
327 result = PySequence_Repeat(tup, n);
328 Py_DECREF(tup);
329 return result;
330}
331
332static int
333structseq_contains(PyStructSequence *obj, PyObject *o)
334{
335 PyObject *tup;
336 int result;
337 tup = make_tuple(obj);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000338 if (!tup)
339 return -1;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000340 result = PySequence_Contains(tup, o);
341 Py_DECREF(tup);
342 return result;
343}
344
345static long
346structseq_hash(PyObject *obj)
347{
348 PyObject *tup;
349 long result;
350 tup = make_tuple((PyStructSequence*) obj);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000351 if (!tup)
352 return -1;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000353 result = PyObject_Hash(tup);
354 Py_DECREF(tup);
355 return result;
356}
357
358static PyObject *
359structseq_richcompare(PyObject *obj, PyObject *o2, int op)
360{
361 PyObject *tup, *result;
362 tup = make_tuple((PyStructSequence*) obj);
363 result = PyObject_RichCompare(tup, o2, op);
364 Py_DECREF(tup);
365 return result;
366}
367
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000368static PyObject *
369structseq_reduce(PyStructSequence* self)
370{
371 PyObject* tup;
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000372 PyObject* dict;
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000373 PyObject* result;
Martin v. Löwiseb079f12006-02-16 14:32:27 +0000374 Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000375 int i;
376
377 n_fields = REAL_SIZE(self);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000378 n_visible_fields = VISIBLE_SIZE(self);
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000379 n_unnamed_fields = UNNAMED_FIELDS(self);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000380 tup = PyTuple_New(n_visible_fields);
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000381 if (!tup) {
382 return NULL;
383 }
384
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000385 dict = PyDict_New();
386 if (!dict) {
387 Py_DECREF(tup);
388 return NULL;
389 }
390
391 for (i = 0; i < n_visible_fields; i++) {
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000392 Py_INCREF(self->ob_item[i]);
393 PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
394 }
395
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000396 for (; i < n_fields; i++) {
Christian Heimes90aa7642007-12-19 02:45:37 +0000397 char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000398 PyDict_SetItemString(dict, n,
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000399 self->ob_item[i]);
400 }
401
Christian Heimes90aa7642007-12-19 02:45:37 +0000402 result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000403
404 Py_DECREF(tup);
405 Py_DECREF(dict);
406
407 return result;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000408}
409
Guido van Rossume82f75a2001-10-18 20:47:51 +0000410static PySequenceMethods structseq_as_sequence = {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000411 (lenfunc)structseq_length,
Guido van Rossume82f75a2001-10-18 20:47:51 +0000412 (binaryfunc)structseq_concat, /* sq_concat */
Martin v. Löwis18e16552006-02-15 17:27:45 +0000413 (ssizeargfunc)structseq_repeat, /* sq_repeat */
414 (ssizeargfunc)structseq_item, /* sq_item */
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000415 0, /* sq_slice */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000416 0, /* sq_ass_item */
417 0, /* sq_ass_slice */
418 (objobjproc)structseq_contains, /* sq_contains */
419};
420
Thomas Woutersed03b412007-08-28 21:37:11 +0000421static PyMappingMethods structseq_as_mapping = {
422 (lenfunc)structseq_length,
423 (binaryfunc)structseq_subscript,
424};
425
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000426static PyMethodDef structseq_methods[] = {
427 {"__reduce__", (PyCFunction)structseq_reduce,
428 METH_NOARGS, NULL},
429 {NULL, NULL}
430};
431
Guido van Rossume82f75a2001-10-18 20:47:51 +0000432static PyTypeObject _struct_sequence_template = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000433 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000434 NULL, /* tp_name */
435 0, /* tp_basicsize */
436 0, /* tp_itemsize */
437 (destructor)structseq_dealloc, /* tp_dealloc */
438 0, /* tp_print */
439 0, /* tp_getattr */
440 0, /* tp_setattr */
441 0, /* tp_compare */
442 (reprfunc)structseq_repr, /* tp_repr */
443 0, /* tp_as_number */
444 &structseq_as_sequence, /* tp_as_sequence */
Thomas Woutersed03b412007-08-28 21:37:11 +0000445 &structseq_as_mapping, /* tp_as_mapping */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000446 structseq_hash, /* tp_hash */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000447 0, /* tp_call */
448 0, /* tp_str */
449 0, /* tp_getattro */
450 0, /* tp_setattro */
451 0, /* tp_as_buffer */
452 Py_TPFLAGS_DEFAULT, /* tp_flags */
453 NULL, /* tp_doc */
454 0, /* tp_traverse */
455 0, /* tp_clear */
456 structseq_richcompare, /* tp_richcompare */
457 0, /* tp_weaklistoffset */
458 0, /* tp_iter */
459 0, /* tp_iternext */
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000460 structseq_methods, /* tp_methods */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000461 NULL, /* tp_members */
462 0, /* tp_getset */
463 0, /* tp_base */
464 0, /* tp_dict */
465 0, /* tp_descr_get */
466 0, /* tp_descr_set */
467 0, /* tp_dictoffset */
468 0, /* tp_init */
469 0, /* tp_alloc */
470 structseq_new, /* tp_new */
471};
472
473void
474PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
475{
476 PyObject *dict;
477 PyMemberDef* members;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000478 int n_members, n_unnamed_members, i, k;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000479
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000480#ifdef Py_TRACE_REFS
481 /* if the type object was chained, unchain it first
482 before overwriting its storage */
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000483 if (type->ob_base.ob_base._ob_next) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000484 _Py_ForgetReference((PyObject*)type);
485 }
486#endif
487
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000488 n_unnamed_members = 0;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000489 for (i = 0; desc->fields[i].name != NULL; ++i)
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000490 if (desc->fields[i].name == PyStructSequence_UnnamedField)
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000491 n_unnamed_members++;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000492 n_members = i;
493
494 memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
495 type->tp_name = desc->name;
496 type->tp_doc = desc->doc;
497 type->tp_basicsize = sizeof(PyStructSequence)+
498 sizeof(PyObject*)*(n_members-1);
499 type->tp_itemsize = 0;
500
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000501 members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
Neal Norwitz8feeabb2002-12-18 23:20:39 +0000502 if (members == NULL)
503 return;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000504
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000505 for (i = k = 0; i < n_members; ++i) {
506 if (desc->fields[i].name == PyStructSequence_UnnamedField)
507 continue;
508 members[k].name = desc->fields[i].name;
509 members[k].type = T_OBJECT;
510 members[k].offset = offsetof(PyStructSequence, ob_item)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000511 + i * sizeof(PyObject*);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000512 members[k].flags = READONLY;
513 members[k].doc = desc->fields[i].doc;
514 k++;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000515 }
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000516 members[k].name = NULL;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000517
518 type->tp_members = members;
519
520 if (PyType_Ready(type) < 0)
521 return;
522 Py_INCREF(type);
523
524 dict = type->tp_dict;
525 PyDict_SetItemString(dict, visible_length_key,
Christian Heimes217cfd12007-12-02 14:31:20 +0000526 PyLong_FromLong((long) desc->n_in_sequence));
Guido van Rossume82f75a2001-10-18 20:47:51 +0000527 PyDict_SetItemString(dict, real_length_key,
Christian Heimes217cfd12007-12-02 14:31:20 +0000528 PyLong_FromLong((long) n_members));
Martin v. Löwisceaa77c2002-10-16 19:10:03 +0000529 PyDict_SetItemString(dict, unnamed_fields_key,
Christian Heimes217cfd12007-12-02 14:31:20 +0000530 PyLong_FromLong((long) n_unnamed_members));
Guido van Rossume82f75a2001-10-18 20:47:51 +0000531}