diff --git a/Lib/test/test_structseq.py b/Lib/test/test_structseq.py index f01bc44b05f..387a89c6ff7 100644 --- a/Lib/test/test_structseq.py +++ b/Lib/test/test_structseq.py @@ -1,7 +1,8 @@ +import os +import time import unittest from test import support -import time class StructSeqTest(unittest.TestCase): @@ -34,6 +35,13 @@ class StructSeqTest(unittest.TestCase): self.assertEqual(repr(t), "time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, " "tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)") + # os.stat() gives a complicated struct sequence. + st = os.stat(__file__) + rep = repr(st) + self.assertTrue(rep.startswith("posix.stat_result")) + self.assertIn("st_mode=", rep) + self.assertIn("st_ino=", rep) + self.assertIn("st_dev=", rep) def test_concat(self): t1 = time.gmtime() diff --git a/Objects/structseq.c b/Objects/structseq.c index 647586c4a41..52ff301ff6d 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -35,12 +35,27 @@ PyStructSequence_New(PyTypeObject *type) obj = PyObject_GC_NewVar(PyStructSequence, type, size); if (obj == NULL) return NULL; + /* Hack the size of the variable object, so invisible fields don't appear + to Python code. */ + Py_SIZE(obj) = VISIBLE_SIZE_TP(type); for (i = 0; i < size; i++) obj->ob_item[i] = NULL; return (PyObject*)obj; } +static void +structseq_dealloc(PyStructSequence *obj) +{ + Py_ssize_t i, size; + + size = REAL_SIZE(obj); + for (i = 0; i < size; ++i) { + Py_XDECREF(obj->ob_item[i]); + } + PyObject_GC_Del(obj); +} + static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -154,8 +169,11 @@ structseq_repr(PyStructSequence *obj) char *cname, *crepr; cname = typ->tp_members[i].name; - if (cname == NULL) + if (cname == NULL) { + PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL" + " for type %.500s", i, typ->tp_name); return NULL; + } val = PyStructSequence_GET_ITEM(obj, i); repr = PyObject_Repr(val); if (repr == NULL) @@ -249,7 +267,7 @@ static PyTypeObject _struct_sequence_template = { NULL, /* tp_name */ sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */ sizeof(PyObject *), /* tp_itemsize */ - 0, /* tp_dealloc */ + (destructor)structseq_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */