structseq.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /* Implementation helper: a struct that looks like a tuple.
  2. See timemodule and posixmodule for example uses.
  3. The structseq helper is considered an internal CPython implementation
  4. detail. Docs for modules using structseqs should call them
  5. "named tuples" (be sure to include a space between the two
  6. words and add a link back to the term in Docs/glossary.rst).
  7. */
  8. #include "Python.h"
  9. #include "pycore_tuple.h" // _PyTuple_FromArray()
  10. #include "pycore_object.h" // _PyObject_GC_TRACK()
  11. #include "structmember.h" // PyMemberDef
  12. #include "pycore_structseq.h" // PyStructSequence_InitType()
  13. #include "pycore_initconfig.h" // _PyStatus_OK()
  14. static const char visible_length_key[] = "n_sequence_fields";
  15. static const char real_length_key[] = "n_fields";
  16. static const char unnamed_fields_key[] = "n_unnamed_fields";
  17. static const char match_args_key[] = "__match_args__";
  18. /* Fields with this name have only a field index, not a field name.
  19. They are only allowed for indices < n_visible_fields. */
  20. const char * const PyStructSequence_UnnamedField = "unnamed field";
  21. static Py_ssize_t
  22. get_type_attr_as_size(PyTypeObject *tp, PyObject *name)
  23. {
  24. PyObject *v = PyDict_GetItemWithError(_PyType_GetDict(tp), name);
  25. if (v == NULL && !PyErr_Occurred()) {
  26. PyErr_Format(PyExc_TypeError,
  27. "Missed attribute '%U' of type %s",
  28. name, tp->tp_name);
  29. return -1;
  30. }
  31. return PyLong_AsSsize_t(v);
  32. }
  33. #define VISIBLE_SIZE(op) Py_SIZE(op)
  34. #define VISIBLE_SIZE_TP(tp) \
  35. get_type_attr_as_size(tp, &_Py_ID(n_sequence_fields))
  36. #define REAL_SIZE_TP(tp) \
  37. get_type_attr_as_size(tp, &_Py_ID(n_fields))
  38. #define REAL_SIZE(op) get_real_size((PyObject *)op)
  39. #define UNNAMED_FIELDS_TP(tp) \
  40. get_type_attr_as_size(tp, &_Py_ID(n_unnamed_fields))
  41. #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
  42. static Py_ssize_t
  43. get_real_size(PyObject *op)
  44. {
  45. // Compute the real size from the visible size (i.e., Py_SIZE()) and the
  46. // number of non-sequence fields accounted for in tp_basicsize.
  47. Py_ssize_t hidden = Py_TYPE(op)->tp_basicsize - offsetof(PyStructSequence, ob_item);
  48. return Py_SIZE(op) + hidden / sizeof(PyObject *);
  49. }
  50. PyObject *
  51. PyStructSequence_New(PyTypeObject *type)
  52. {
  53. PyStructSequence *obj;
  54. Py_ssize_t size = REAL_SIZE_TP(type), i;
  55. if (size < 0) {
  56. return NULL;
  57. }
  58. Py_ssize_t vsize = VISIBLE_SIZE_TP(type);
  59. if (vsize < 0) {
  60. return NULL;
  61. }
  62. obj = PyObject_GC_NewVar(PyStructSequence, type, size);
  63. if (obj == NULL)
  64. return NULL;
  65. /* Hack the size of the variable object, so invisible fields don't appear
  66. to Python code. */
  67. Py_SET_SIZE(obj, vsize);
  68. for (i = 0; i < size; i++)
  69. obj->ob_item[i] = NULL;
  70. return (PyObject*)obj;
  71. }
  72. void
  73. PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v)
  74. {
  75. PyStructSequence_SET_ITEM(op, i, v);
  76. }
  77. PyObject*
  78. PyStructSequence_GetItem(PyObject* op, Py_ssize_t i)
  79. {
  80. return PyStructSequence_GET_ITEM(op, i);
  81. }
  82. static int
  83. structseq_traverse(PyStructSequence *obj, visitproc visit, void *arg)
  84. {
  85. if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_HEAPTYPE) {
  86. Py_VISIT(Py_TYPE(obj));
  87. }
  88. Py_ssize_t i, size;
  89. size = REAL_SIZE(obj);
  90. for (i = 0; i < size; ++i) {
  91. Py_VISIT(obj->ob_item[i]);
  92. }
  93. return 0;
  94. }
  95. static void
  96. structseq_dealloc(PyStructSequence *obj)
  97. {
  98. Py_ssize_t i, size;
  99. PyObject_GC_UnTrack(obj);
  100. PyTypeObject *tp = Py_TYPE(obj);
  101. // gh-122527: We can't use REAL_SIZE_TP() or any macros that access the
  102. // type's dictionary here, because the dictionary may have already been
  103. // cleared by the garbage collector.
  104. size = REAL_SIZE(obj);
  105. for (i = 0; i < size; ++i) {
  106. Py_XDECREF(obj->ob_item[i]);
  107. }
  108. PyObject_GC_Del(obj);
  109. if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) {
  110. Py_DECREF(tp);
  111. }
  112. }
  113. /*[clinic input]
  114. class structseq "PyStructSequence *" "NULL"
  115. [clinic start generated code]*/
  116. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9d781c6922c77752]*/
  117. #include "clinic/structseq.c.h"
  118. /*[clinic input]
  119. @classmethod
  120. structseq.__new__ as structseq_new
  121. sequence as arg: object
  122. dict: object(c_default="NULL") = {}
  123. [clinic start generated code]*/
  124. static PyObject *
  125. structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict)
  126. /*[clinic end generated code: output=baa082e788b171da input=90532511101aa3fb]*/
  127. {
  128. PyObject *ob;
  129. PyStructSequence *res = NULL;
  130. Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
  131. min_len = VISIBLE_SIZE_TP(type);
  132. if (min_len < 0) {
  133. return NULL;
  134. }
  135. max_len = REAL_SIZE_TP(type);
  136. if (max_len < 0) {
  137. return NULL;
  138. }
  139. n_unnamed_fields = UNNAMED_FIELDS_TP(type);
  140. if (n_unnamed_fields < 0) {
  141. return NULL;
  142. }
  143. arg = PySequence_Fast(arg, "constructor requires a sequence");
  144. if (!arg) {
  145. return NULL;
  146. }
  147. if (dict && !PyDict_Check(dict)) {
  148. PyErr_Format(PyExc_TypeError,
  149. "%.500s() takes a dict as second arg, if any",
  150. type->tp_name);
  151. Py_DECREF(arg);
  152. return NULL;
  153. }
  154. len = PySequence_Fast_GET_SIZE(arg);
  155. if (min_len != max_len) {
  156. if (len < min_len) {
  157. PyErr_Format(PyExc_TypeError,
  158. "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
  159. type->tp_name, min_len, len);
  160. Py_DECREF(arg);
  161. return NULL;
  162. }
  163. if (len > max_len) {
  164. PyErr_Format(PyExc_TypeError,
  165. "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
  166. type->tp_name, max_len, len);
  167. Py_DECREF(arg);
  168. return NULL;
  169. }
  170. }
  171. else {
  172. if (len != min_len) {
  173. PyErr_Format(PyExc_TypeError,
  174. "%.500s() takes a %zd-sequence (%zd-sequence given)",
  175. type->tp_name, min_len, len);
  176. Py_DECREF(arg);
  177. return NULL;
  178. }
  179. }
  180. res = (PyStructSequence*) PyStructSequence_New(type);
  181. if (res == NULL) {
  182. Py_DECREF(arg);
  183. return NULL;
  184. }
  185. for (i = 0; i < len; ++i) {
  186. PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
  187. res->ob_item[i] = Py_NewRef(v);
  188. }
  189. Py_DECREF(arg);
  190. for (; i < max_len; ++i) {
  191. if (dict == NULL) {
  192. ob = Py_None;
  193. }
  194. else {
  195. ob = _PyDict_GetItemStringWithError(dict,
  196. type->tp_members[i-n_unnamed_fields].name);
  197. if (ob == NULL) {
  198. if (PyErr_Occurred()) {
  199. Py_DECREF(res);
  200. return NULL;
  201. }
  202. ob = Py_None;
  203. }
  204. }
  205. res->ob_item[i] = Py_NewRef(ob);
  206. }
  207. _PyObject_GC_TRACK(res);
  208. return (PyObject*) res;
  209. }
  210. static PyObject *
  211. structseq_repr(PyStructSequence *obj)
  212. {
  213. PyTypeObject *typ = Py_TYPE(obj);
  214. _PyUnicodeWriter writer;
  215. /* Write "typename(" */
  216. PyObject *type_name = PyUnicode_DecodeUTF8(typ->tp_name,
  217. strlen(typ->tp_name),
  218. NULL);
  219. if (type_name == NULL) {
  220. return NULL;
  221. }
  222. _PyUnicodeWriter_Init(&writer);
  223. writer.overallocate = 1;
  224. /* count 5 characters per item: "x=1, " */
  225. writer.min_length = (PyUnicode_GET_LENGTH(type_name) + 1
  226. + VISIBLE_SIZE(obj) * 5 + 1);
  227. if (_PyUnicodeWriter_WriteStr(&writer, type_name) < 0) {
  228. Py_DECREF(type_name);
  229. goto error;
  230. }
  231. Py_DECREF(type_name);
  232. if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) {
  233. goto error;
  234. }
  235. for (Py_ssize_t i=0; i < VISIBLE_SIZE(obj); i++) {
  236. if (i > 0) {
  237. /* Write ", " */
  238. if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
  239. goto error;
  240. }
  241. }
  242. /* Write "name=repr" */
  243. const char *name_utf8 = typ->tp_members[i].name;
  244. if (name_utf8 == NULL) {
  245. PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %zd name is NULL"
  246. " for type %.500s", i, typ->tp_name);
  247. goto error;
  248. }
  249. PyObject *name = PyUnicode_DecodeUTF8(name_utf8, strlen(name_utf8), NULL);
  250. if (name == NULL) {
  251. goto error;
  252. }
  253. if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) {
  254. Py_DECREF(name);
  255. goto error;
  256. }
  257. Py_DECREF(name);
  258. if (_PyUnicodeWriter_WriteChar(&writer, '=') < 0) {
  259. goto error;
  260. }
  261. PyObject *value = PyStructSequence_GET_ITEM(obj, i);
  262. assert(value != NULL);
  263. PyObject *repr = PyObject_Repr(value);
  264. if (repr == NULL) {
  265. goto error;
  266. }
  267. if (_PyUnicodeWriter_WriteStr(&writer, repr) < 0) {
  268. Py_DECREF(repr);
  269. goto error;
  270. }
  271. Py_DECREF(repr);
  272. }
  273. if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) {
  274. goto error;
  275. }
  276. return _PyUnicodeWriter_Finish(&writer);
  277. error:
  278. _PyUnicodeWriter_Dealloc(&writer);
  279. return NULL;
  280. }
  281. static PyObject *
  282. structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored))
  283. {
  284. PyObject* tup = NULL;
  285. PyObject* dict = NULL;
  286. PyObject* result;
  287. Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i;
  288. n_fields = REAL_SIZE(self);
  289. if (n_fields < 0) {
  290. return NULL;
  291. }
  292. n_visible_fields = VISIBLE_SIZE(self);
  293. n_unnamed_fields = UNNAMED_FIELDS(self);
  294. if (n_unnamed_fields < 0) {
  295. return NULL;
  296. }
  297. tup = _PyTuple_FromArray(self->ob_item, n_visible_fields);
  298. if (!tup)
  299. goto error;
  300. dict = PyDict_New();
  301. if (!dict)
  302. goto error;
  303. for (i = n_visible_fields; i < n_fields; i++) {
  304. const char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
  305. if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0)
  306. goto error;
  307. }
  308. result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
  309. Py_DECREF(tup);
  310. Py_DECREF(dict);
  311. return result;
  312. error:
  313. Py_XDECREF(tup);
  314. Py_XDECREF(dict);
  315. return NULL;
  316. }
  317. static PyMethodDef structseq_methods[] = {
  318. {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL},
  319. {NULL, NULL}
  320. };
  321. static Py_ssize_t
  322. count_members(PyStructSequence_Desc *desc, Py_ssize_t *n_unnamed_members) {
  323. Py_ssize_t i;
  324. *n_unnamed_members = 0;
  325. for (i = 0; desc->fields[i].name != NULL; ++i) {
  326. if (desc->fields[i].name == PyStructSequence_UnnamedField) {
  327. (*n_unnamed_members)++;
  328. }
  329. }
  330. return i;
  331. }
  332. static int
  333. initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict,
  334. Py_ssize_t n_members, Py_ssize_t n_unnamed_members) {
  335. PyObject *v;
  336. #define SET_DICT_FROM_SIZE(key, value) \
  337. do { \
  338. v = PyLong_FromSsize_t(value); \
  339. if (v == NULL) { \
  340. return -1; \
  341. } \
  342. if (PyDict_SetItemString(dict, key, v) < 0) { \
  343. Py_DECREF(v); \
  344. return -1; \
  345. } \
  346. Py_DECREF(v); \
  347. } while (0)
  348. SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence);
  349. SET_DICT_FROM_SIZE(real_length_key, n_members);
  350. SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members);
  351. // Prepare and set __match_args__
  352. Py_ssize_t i, k;
  353. PyObject* keys = PyTuple_New(desc->n_in_sequence);
  354. if (keys == NULL) {
  355. return -1;
  356. }
  357. for (i = k = 0; i < desc->n_in_sequence; ++i) {
  358. if (desc->fields[i].name == PyStructSequence_UnnamedField) {
  359. continue;
  360. }
  361. PyObject* new_member = PyUnicode_FromString(desc->fields[i].name);
  362. if (new_member == NULL) {
  363. goto error;
  364. }
  365. PyTuple_SET_ITEM(keys, k, new_member);
  366. k++;
  367. }
  368. if (_PyTuple_Resize(&keys, k) == -1) {
  369. goto error;
  370. }
  371. if (PyDict_SetItemString(dict, match_args_key, keys) < 0) {
  372. goto error;
  373. }
  374. Py_DECREF(keys);
  375. return 0;
  376. error:
  377. Py_DECREF(keys);
  378. return -1;
  379. }
  380. static PyMemberDef *
  381. initialize_members(PyStructSequence_Desc *desc,
  382. Py_ssize_t n_members, Py_ssize_t n_unnamed_members)
  383. {
  384. PyMemberDef *members;
  385. members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1);
  386. if (members == NULL) {
  387. PyErr_NoMemory();
  388. return NULL;
  389. }
  390. Py_ssize_t i, k;
  391. for (i = k = 0; i < n_members; ++i) {
  392. if (desc->fields[i].name == PyStructSequence_UnnamedField) {
  393. continue;
  394. }
  395. /* The names and docstrings in these MemberDefs are statically */
  396. /* allocated so it is expected that they'll outlive the MemberDef */
  397. members[k].name = desc->fields[i].name;
  398. members[k].type = T_OBJECT;
  399. members[k].offset = offsetof(PyStructSequence, ob_item)
  400. + i * sizeof(PyObject*);
  401. members[k].flags = READONLY;
  402. members[k].doc = desc->fields[i].doc;
  403. k++;
  404. }
  405. members[k].name = NULL;
  406. return members;
  407. }
  408. static void
  409. initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc,
  410. PyMemberDef *tp_members, Py_ssize_t n_members,
  411. unsigned long tp_flags)
  412. {
  413. type->tp_name = desc->name;
  414. // Account for hidden members in tp_basicsize because they are not
  415. // included in the variable size.
  416. Py_ssize_t n_hidden = n_members - desc->n_in_sequence;
  417. type->tp_basicsize = sizeof(PyStructSequence) + (n_hidden - 1) * sizeof(PyObject *);
  418. type->tp_itemsize = sizeof(PyObject *);
  419. type->tp_dealloc = (destructor)structseq_dealloc;
  420. type->tp_repr = (reprfunc)structseq_repr;
  421. type->tp_doc = desc->doc;
  422. type->tp_base = &PyTuple_Type;
  423. type->tp_methods = structseq_methods;
  424. type->tp_new = structseq_new;
  425. type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags;
  426. type->tp_traverse = (traverseproc) structseq_traverse;
  427. type->tp_members = tp_members;
  428. }
  429. static int
  430. initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc,
  431. Py_ssize_t n_members, Py_ssize_t n_unnamed_members) {
  432. /* initialize_static_fields() should have been called already. */
  433. if (PyType_Ready(type) < 0) {
  434. return -1;
  435. }
  436. Py_INCREF(type);
  437. if (initialize_structseq_dict(
  438. desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
  439. Py_DECREF(type);
  440. return -1;
  441. }
  442. return 0;
  443. }
  444. int
  445. _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
  446. PyTypeObject *type,
  447. PyStructSequence_Desc *desc,
  448. unsigned long tp_flags)
  449. {
  450. Py_ssize_t n_unnamed_members;
  451. Py_ssize_t n_members = count_members(desc, &n_unnamed_members);
  452. PyMemberDef *members = NULL;
  453. if ((type->tp_flags & Py_TPFLAGS_READY) == 0) {
  454. assert(type->tp_name == NULL);
  455. assert(type->tp_members == NULL);
  456. assert(type->tp_base == NULL);
  457. members = initialize_members(desc, n_members, n_unnamed_members);
  458. if (members == NULL) {
  459. goto error;
  460. }
  461. initialize_static_fields(type, desc, members, n_members, tp_flags);
  462. _Py_SetImmortal(type);
  463. }
  464. #ifndef NDEBUG
  465. else {
  466. // Ensure that the type was initialized.
  467. assert(type->tp_name != NULL);
  468. assert(type->tp_members != NULL);
  469. assert(type->tp_base == &PyTuple_Type);
  470. assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
  471. assert(_Py_IsImmortal(type));
  472. }
  473. #endif
  474. if (_PyStaticType_InitBuiltin(interp, type) < 0) {
  475. PyErr_Format(PyExc_RuntimeError,
  476. "Can't initialize builtin type %s",
  477. desc->name);
  478. goto error;
  479. }
  480. if (initialize_structseq_dict(
  481. desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0)
  482. {
  483. goto error;
  484. }
  485. return 0;
  486. error:
  487. if (members != NULL) {
  488. PyMem_Free(members);
  489. }
  490. return -1;
  491. }
  492. int
  493. PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
  494. {
  495. PyMemberDef *members;
  496. Py_ssize_t n_members, n_unnamed_members;
  497. #ifdef Py_TRACE_REFS
  498. /* if the type object was chained, unchain it first
  499. before overwriting its storage */
  500. if (type->ob_base.ob_base._ob_next) {
  501. _Py_ForgetReference((PyObject *)type);
  502. }
  503. #endif
  504. /* PyTypeObject has already been initialized */
  505. if (Py_REFCNT(type) != 0) {
  506. PyErr_BadInternalCall();
  507. return -1;
  508. }
  509. n_members = count_members(desc, &n_unnamed_members);
  510. members = initialize_members(desc, n_members, n_unnamed_members);
  511. if (members == NULL) {
  512. return -1;
  513. }
  514. initialize_static_fields(type, desc, members, n_members, 0);
  515. if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) {
  516. PyMem_Free(members);
  517. return -1;
  518. }
  519. return 0;
  520. }
  521. void
  522. PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
  523. {
  524. (void)PyStructSequence_InitType2(type, desc);
  525. }
  526. /* This is exposed in the internal API, not the public API.
  527. It is only called on builtin static types, which are all
  528. initialized via _PyStructSequence_InitBuiltinWithFlags(). */
  529. void
  530. _PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
  531. {
  532. // Ensure that the type is initialized
  533. assert(type->tp_name != NULL);
  534. assert(type->tp_base == &PyTuple_Type);
  535. assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
  536. assert(_Py_IsImmortal(type));
  537. // Cannot delete a type if it still has subclasses
  538. if (_PyType_HasSubclasses(type)) {
  539. // XXX Shouldn't this be an error?
  540. return;
  541. }
  542. _PyStaticType_Dealloc(interp, type);
  543. if (_Py_IsMainInterpreter(interp)) {
  544. // Undo _PyStructSequence_InitBuiltinWithFlags().
  545. type->tp_name = NULL;
  546. PyMem_Free(type->tp_members);
  547. type->tp_members = NULL;
  548. type->tp_base = NULL;
  549. }
  550. }
  551. PyTypeObject *
  552. _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
  553. {
  554. PyMemberDef *members;
  555. PyTypeObject *type;
  556. PyType_Slot slots[8];
  557. PyType_Spec spec;
  558. Py_ssize_t n_members, n_unnamed_members;
  559. /* Initialize MemberDefs */
  560. n_members = count_members(desc, &n_unnamed_members);
  561. members = initialize_members(desc, n_members, n_unnamed_members);
  562. if (members == NULL) {
  563. return NULL;
  564. }
  565. /* Initialize Slots */
  566. slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc};
  567. slots[1] = (PyType_Slot){Py_tp_repr, (reprfunc)structseq_repr};
  568. slots[2] = (PyType_Slot){Py_tp_doc, (void *)desc->doc};
  569. slots[3] = (PyType_Slot){Py_tp_methods, structseq_methods};
  570. slots[4] = (PyType_Slot){Py_tp_new, structseq_new};
  571. slots[5] = (PyType_Slot){Py_tp_members, members};
  572. slots[6] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse};
  573. slots[7] = (PyType_Slot){0, 0};
  574. /* Initialize Spec */
  575. /* The name in this PyType_Spec is statically allocated so it is */
  576. /* expected that it'll outlive the PyType_Spec */
  577. spec.name = desc->name;
  578. Py_ssize_t hidden = n_members - desc->n_in_sequence;
  579. spec.basicsize = (int)(sizeof(PyStructSequence) + (hidden - 1) * sizeof(PyObject *));
  580. spec.itemsize = sizeof(PyObject *);
  581. spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags;
  582. spec.slots = slots;
  583. type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type);
  584. PyMem_Free(members);
  585. if (type == NULL) {
  586. return NULL;
  587. }
  588. if (initialize_structseq_dict(
  589. desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
  590. Py_DECREF(type);
  591. return NULL;
  592. }
  593. return type;
  594. }
  595. PyTypeObject *
  596. PyStructSequence_NewType(PyStructSequence_Desc *desc)
  597. {
  598. return _PyStructSequence_NewType(desc, 0);
  599. }