blob: 5489aef6d087475abf3b1ad129d0cd6622b5b0aa [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"
Guido van Rossume82f75a2001-10-18 20:47:51 +00006
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02007static const char visible_length_key[] = "n_sequence_fields";
8static const char real_length_key[] = "n_fields";
9static const char unnamed_fields_key[] = "n_unnamed_fields";
Guido van Rossume82f75a2001-10-18 20:47:51 +000010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000011/* Fields with this name have only a field index, not a field name.
Martin v. Löwisf607bda2002-10-16 18:27:39 +000012 They are only allowed for indices < n_visible_fields. */
13char *PyStructSequence_UnnamedField = "unnamed field";
Victor Stinner26f91992013-07-17 01:22:45 +020014_Py_IDENTIFIER(n_sequence_fields);
15_Py_IDENTIFIER(n_fields);
16_Py_IDENTIFIER(n_unnamed_fields);
Martin v. Löwisf607bda2002-10-16 18:27:39 +000017
Christian Heimes90aa7642007-12-19 02:45:37 +000018#define VISIBLE_SIZE(op) Py_SIZE(op)
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030019#define VISIBLE_SIZE_TP(tp) PyLong_AsSsize_t( \
Victor Stinner26f91992013-07-17 01:22:45 +020020 _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields))
Guido van Rossume82f75a2001-10-18 20:47:51 +000021
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030022#define REAL_SIZE_TP(tp) PyLong_AsSsize_t( \
Victor Stinner26f91992013-07-17 01:22:45 +020023 _PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields))
Christian Heimes90aa7642007-12-19 02:45:37 +000024#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
Guido van Rossume82f75a2001-10-18 20:47:51 +000025
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030026#define UNNAMED_FIELDS_TP(tp) PyLong_AsSsize_t( \
Victor Stinner26f91992013-07-17 01:22:45 +020027 _PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields))
Christian Heimes90aa7642007-12-19 02:45:37 +000028#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
Martin v. Löwisceaa77c2002-10-16 19:10:03 +000029
Guido van Rossume82f75a2001-10-18 20:47:51 +000030
31PyObject *
32PyStructSequence_New(PyTypeObject *type)
33{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 PyStructSequence *obj;
Benjamin Petersonccabcd42010-07-07 20:54:01 +000035 Py_ssize_t size = REAL_SIZE_TP(type), i;
Christian Heimesd32ed6f2008-01-14 18:49:24 +000036
Benjamin Petersonccabcd42010-07-07 20:54:01 +000037 obj = PyObject_GC_NewVar(PyStructSequence, type, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 if (obj == NULL)
39 return NULL;
Benjamin Petersond02441e2010-07-08 22:33:03 +000040 /* Hack the size of the variable object, so invisible fields don't appear
41 to Python code. */
42 Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
Benjamin Petersonccabcd42010-07-07 20:54:01 +000043 for (i = 0; i < size; i++)
44 obj->ob_item[i] = NULL;
Guido van Rossume82f75a2001-10-18 20:47:51 +000045
Benjamin Petersonccabcd42010-07-07 20:54:01 +000046 return (PyObject*)obj;
Thomas Woutersed03b412007-08-28 21:37:11 +000047}
48
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000049void
50PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v)
51{
52 PyStructSequence_SET_ITEM(op, i, v);
53}
54
55PyObject*
56PyStructSequence_GetItem(PyObject* op, Py_ssize_t i)
57{
58 return PyStructSequence_GET_ITEM(op, i);
59}
60
Benjamin Petersond02441e2010-07-08 22:33:03 +000061static void
62structseq_dealloc(PyStructSequence *obj)
63{
64 Py_ssize_t i, size;
Victor Stinner26f91992013-07-17 01:22:45 +020065
Benjamin Petersond02441e2010-07-08 22:33:03 +000066 size = REAL_SIZE(obj);
67 for (i = 0; i < size; ++i) {
68 Py_XDECREF(obj->ob_item[i]);
69 }
70 PyObject_GC_Del(obj);
71}
72
Thomas Woutersed03b412007-08-28 21:37:11 +000073static PyObject *
Guido van Rossume82f75a2001-10-18 20:47:51 +000074structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
75{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 PyObject *arg = NULL;
77 PyObject *dict = NULL;
78 PyObject *ob;
79 PyStructSequence *res = NULL;
80 Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
81 static char *kwlist[] = {"sequence", "dict", 0};
Guido van Rossume82f75a2001-10-18 20:47:51 +000082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
84 kwlist, &arg, &dict))
85 return NULL;
Guido van Rossume82f75a2001-10-18 20:47:51 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 arg = PySequence_Fast(arg, "constructor requires a sequence");
Michael W. Hudsonce358e32002-03-06 17:07:49 +000088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 if (!arg) {
90 return NULL;
91 }
Guido van Rossume82f75a2001-10-18 20:47:51 +000092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 if (dict && !PyDict_Check(dict)) {
94 PyErr_Format(PyExc_TypeError,
95 "%.500s() takes a dict as second arg, if any",
96 type->tp_name);
97 Py_DECREF(arg);
98 return NULL;
99 }
Guido van Rossume82f75a2001-10-18 20:47:51 +0000100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 len = PySequence_Fast_GET_SIZE(arg);
102 min_len = VISIBLE_SIZE_TP(type);
103 max_len = REAL_SIZE_TP(type);
104 n_unnamed_fields = UNNAMED_FIELDS_TP(type);
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 if (min_len != max_len) {
107 if (len < min_len) {
108 PyErr_Format(PyExc_TypeError,
Antoine Pitrou4b3c7842012-02-15 02:52:58 +0100109 "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
110 type->tp_name, min_len, len);
111 Py_DECREF(arg);
112 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 }
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 if (len > max_len) {
116 PyErr_Format(PyExc_TypeError,
Antoine Pitrou4b3c7842012-02-15 02:52:58 +0100117 "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
118 type->tp_name, max_len, len);
119 Py_DECREF(arg);
120 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
122 }
123 else {
124 if (len != min_len) {
125 PyErr_Format(PyExc_TypeError,
Antoine Pitrou4b3c7842012-02-15 02:52:58 +0100126 "%.500s() takes a %zd-sequence (%zd-sequence given)",
127 type->tp_name, min_len, len);
128 Py_DECREF(arg);
129 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 }
131 }
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 res = (PyStructSequence*) PyStructSequence_New(type);
134 if (res == NULL) {
Antoine Pitrou37784ba2012-02-15 02:51:43 +0100135 Py_DECREF(arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 return NULL;
137 }
138 for (i = 0; i < len; ++i) {
139 PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
140 Py_INCREF(v);
141 res->ob_item[i] = v;
142 }
143 for (; i < max_len; ++i) {
144 if (dict && (ob = PyDict_GetItemString(
145 dict, type->tp_members[i-n_unnamed_fields].name))) {
146 }
147 else {
148 ob = Py_None;
149 }
150 Py_INCREF(ob);
151 res->ob_item[i] = ob;
152 }
153
154 Py_DECREF(arg);
155 return (PyObject*) res;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000156}
157
Guido van Rossume82f75a2001-10-18 20:47:51 +0000158
159static PyObject *
160structseq_repr(PyStructSequence *obj)
161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 /* buffer and type size were chosen well considered. */
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000163#define REPR_BUFFER_SIZE 512
164#define TYPE_MAXSIZE 100
165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 PyTypeObject *typ = Py_TYPE(obj);
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300167 Py_ssize_t i;
168 int removelast = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 Py_ssize_t len;
170 char buf[REPR_BUFFER_SIZE];
171 char *endofbuf, *pbuf = buf;
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 /* pointer to end of writeable buffer; safes space for "...)\0" */
174 endofbuf= &buf[REPR_BUFFER_SIZE-5];
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 /* "typename(", limited to TYPE_MAXSIZE */
177 len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
178 strlen(typ->tp_name);
179 strncpy(pbuf, typ->tp_name, len);
180 pbuf += len;
181 *pbuf++ = '(';
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 for (i=0; i < VISIBLE_SIZE(obj); i++) {
184 PyObject *val, *repr;
185 char *cname, *crepr;
Christian Heimesd32ed6f2008-01-14 18:49:24 +0000186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 cname = typ->tp_members[i].name;
Benjamin Petersond02441e2010-07-08 22:33:03 +0000188 if (cname == NULL) {
189 PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL"
190 " for type %.500s", i, typ->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 return NULL;
Benjamin Petersond02441e2010-07-08 22:33:03 +0000192 }
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000193 val = PyStructSequence_GET_ITEM(obj, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 repr = PyObject_Repr(val);
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000195 if (repr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 return NULL;
Serhiy Storchaka06515832016-11-20 09:13:07 +0200197 crepr = PyUnicode_AsUTF8(repr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 if (crepr == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 Py_DECREF(repr);
200 return NULL;
201 }
202
203 /* + 3: keep space for "=" and ", " */
204 len = strlen(cname) + strlen(crepr) + 3;
205 if ((pbuf+len) <= endofbuf) {
206 strcpy(pbuf, cname);
207 pbuf += strlen(cname);
208 *pbuf++ = '=';
209 strcpy(pbuf, crepr);
210 pbuf += strlen(crepr);
211 *pbuf++ = ',';
212 *pbuf++ = ' ';
213 removelast = 1;
214 Py_DECREF(repr);
215 }
216 else {
217 strcpy(pbuf, "...");
218 pbuf += 3;
219 removelast = 0;
220 Py_DECREF(repr);
221 break;
222 }
223 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 if (removelast) {
225 /* overwrite last ", " */
226 pbuf-=2;
227 }
228 *pbuf++ = ')';
229 *pbuf = '\0';
230
231 return PyUnicode_FromString(buf);
Guido van Rossume82f75a2001-10-18 20:47:51 +0000232}
233
234static PyObject *
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000235structseq_reduce(PyStructSequence* self)
236{
Victor Stinner9a146ee2013-07-17 13:41:39 +0200237 PyObject* tup = NULL;
238 PyObject* dict = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 PyObject* result;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300240 Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 n_fields = REAL_SIZE(self);
243 n_visible_fields = VISIBLE_SIZE(self);
244 n_unnamed_fields = UNNAMED_FIELDS(self);
245 tup = PyTuple_New(n_visible_fields);
Victor Stinner9a146ee2013-07-17 13:41:39 +0200246 if (!tup)
247 goto error;
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 dict = PyDict_New();
Victor Stinner9a146ee2013-07-17 13:41:39 +0200250 if (!dict)
251 goto error;
Michael W. Hudsonce358e32002-03-06 17:07:49 +0000252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 for (i = 0; i < n_visible_fields; i++) {
254 Py_INCREF(self->ob_item[i]);
255 PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
256 }
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 for (; i < n_fields; i++) {
259 char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
Victor Stinner9a146ee2013-07-17 13:41:39 +0200260 if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0)
261 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 }
Michael W. Hudson70ffddf2002-03-07 15:13:40 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
265
266 Py_DECREF(tup);
267 Py_DECREF(dict);
268
269 return result;
Victor Stinner9a146ee2013-07-17 13:41:39 +0200270
271error:
272 Py_XDECREF(tup);
273 Py_XDECREF(dict);
274 return NULL;
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000275}
276
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000277static PyMethodDef structseq_methods[] = {
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000278 {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 {NULL, NULL}
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000280};
281
Guido van Rossume82f75a2001-10-18 20:47:51 +0000282static PyTypeObject _struct_sequence_template = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 PyVarObject_HEAD_INIT(&PyType_Type, 0)
284 NULL, /* tp_name */
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000285 sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */
286 sizeof(PyObject *), /* tp_itemsize */
Benjamin Petersond02441e2010-07-08 22:33:03 +0000287 (destructor)structseq_dealloc, /* tp_dealloc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 0, /* tp_print */
289 0, /* tp_getattr */
290 0, /* tp_setattr */
291 0, /* tp_reserved */
292 (reprfunc)structseq_repr, /* tp_repr */
293 0, /* tp_as_number */
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000294 0, /* tp_as_sequence */
295 0, /* tp_as_mapping */
296 0, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 0, /* tp_call */
298 0, /* tp_str */
299 0, /* tp_getattro */
300 0, /* tp_setattro */
301 0, /* tp_as_buffer */
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000302 Py_TPFLAGS_DEFAULT, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 NULL, /* tp_doc */
304 0, /* tp_traverse */
305 0, /* tp_clear */
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000306 0, /* tp_richcompare */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 0, /* tp_weaklistoffset */
308 0, /* tp_iter */
309 0, /* tp_iternext */
310 structseq_methods, /* tp_methods */
311 NULL, /* tp_members */
312 0, /* tp_getset */
313 0, /* tp_base */
314 0, /* tp_dict */
315 0, /* tp_descr_get */
316 0, /* tp_descr_set */
317 0, /* tp_dictoffset */
318 0, /* tp_init */
319 0, /* tp_alloc */
320 structseq_new, /* tp_new */
Guido van Rossume82f75a2001-10-18 20:47:51 +0000321};
322
Victor Stinner1c8f0592013-07-22 22:24:54 +0200323int
324PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
Guido van Rossume82f75a2001-10-18 20:47:51 +0000325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyObject *dict;
327 PyMemberDef* members;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300328 Py_ssize_t n_members, n_unnamed_members, i, k;
Victor Stinner1c8f0592013-07-22 22:24:54 +0200329 PyObject *v;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000330
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331#ifdef Py_TRACE_REFS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 /* if the type object was chained, unchain it first
333 before overwriting its storage */
334 if (type->ob_base.ob_base._ob_next) {
335 _Py_ForgetReference((PyObject*)type);
336 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337#endif
338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 n_unnamed_members = 0;
340 for (i = 0; desc->fields[i].name != NULL; ++i)
341 if (desc->fields[i].name == PyStructSequence_UnnamedField)
342 n_unnamed_members++;
343 n_members = i;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
Benjamin Petersonccabcd42010-07-07 20:54:01 +0000346 type->tp_base = &PyTuple_Type;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 type->tp_name = desc->name;
348 type->tp_doc = desc->doc;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200351 if (members == NULL) {
352 PyErr_NoMemory();
353 return -1;
354 }
Guido van Rossume82f75a2001-10-18 20:47:51 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 for (i = k = 0; i < n_members; ++i) {
357 if (desc->fields[i].name == PyStructSequence_UnnamedField)
358 continue;
359 members[k].name = desc->fields[i].name;
360 members[k].type = T_OBJECT;
361 members[k].offset = offsetof(PyStructSequence, ob_item)
362 + i * sizeof(PyObject*);
363 members[k].flags = READONLY;
364 members[k].doc = desc->fields[i].doc;
365 k++;
366 }
367 members[k].name = NULL;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 type->tp_members = members;
Guido van Rossume82f75a2001-10-18 20:47:51 +0000370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 if (PyType_Ready(type) < 0)
Victor Stinner1c8f0592013-07-22 22:24:54 +0200372 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 Py_INCREF(type);
Neal Norwitz2f99b242008-08-24 05:48:10 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 dict = type->tp_dict;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300376#define SET_DICT_FROM_SIZE(key, value) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 do { \
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300378 v = PyLong_FromSsize_t(value); \
Victor Stinner1c8f0592013-07-22 22:24:54 +0200379 if (v == NULL) \
380 return -1; \
381 if (PyDict_SetItemString(dict, key, v) < 0) { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 Py_DECREF(v); \
Victor Stinner1c8f0592013-07-22 22:24:54 +0200383 return -1; \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 } \
Victor Stinner1c8f0592013-07-22 22:24:54 +0200385 Py_DECREF(v); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 } while (0)
387
Serhiy Storchaka56f6e762015-09-06 21:25:30 +0300388 SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence);
389 SET_DICT_FROM_SIZE(real_length_key, n_members);
390 SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200391
392 return 0;
393}
394
395void
396PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
397{
398 (void)PyStructSequence_InitType2(type, desc);
Guido van Rossume82f75a2001-10-18 20:47:51 +0000399}
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000400
401PyTypeObject*
402PyStructSequence_NewType(PyStructSequence_Desc *desc)
403{
Victor Stinner26f91992013-07-17 01:22:45 +0200404 PyTypeObject *result;
405
406 result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200407 if (result == NULL)
408 return NULL;
409 if (PyStructSequence_InitType2(result, desc) < 0) {
410 Py_DECREF(result);
411 return NULL;
Stefan Krah6b962862012-08-19 11:20:41 +0200412 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000413 return result;
414}
Victor Stinner26f91992013-07-17 01:22:45 +0200415
416int _PyStructSequence_Init(void)
417{
418 if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL
419 || _PyUnicode_FromId(&PyId_n_fields) == NULL
420 || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL)
421 return -1;
422
423 return 0;
424}