[3.12] gh-112358: Fix Python 3.12 regression with subclassing struct.Struct (GH-112424) by mdickinson · Pull Request #112426 · python/cpython

Expand Up @@ -1550,9 +1550,28 @@ prepare_s(PyStructObject *self) return -1; }
static PyObject * s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *self;
assert(type != NULL); allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); assert(alloc_func != NULL);
self = alloc_func(type, 0); if (self != NULL) { PyStructObject *s = (PyStructObject*)self; s->s_format = Py_NewRef(Py_None); s->s_codes = NULL; s->s_size = -1; s->s_len = -1; } return self; }
/*[clinic input] @classmethod Struct.__new__ Struct.__init__
format: object
Expand All @@ -1564,49 +1583,36 @@ the format string. See help(struct) for more on format strings. [clinic start generated code]*/
static PyObject * Struct_impl(PyTypeObject *type, PyObject *format) /*[clinic end generated code: output=49468b044e334308 input=8b91868eb1df0e28]*/ static int Struct___init___impl(PyStructObject *self, PyObject *format) /*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ { allocfunc alloc = PyType_GetSlot(type, Py_tp_alloc); assert(alloc != NULL); PyStructObject *self = (PyStructObject *)alloc(type, 0);
if (self == NULL) { return NULL; } int ret = 0;
if (PyUnicode_Check(format)) { format = PyUnicode_AsASCIIString(format); if (format == NULL) { Py_DECREF(self); return NULL; } if (format == NULL) return -1; } else { Py_INCREF(format); }
if (!PyBytes_Check(format)) { Py_DECREF(format); Py_DECREF(self); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a str or bytes object, " "not %.200s", _PyType_Name(Py_TYPE(format))); return NULL; return -1; }
self->s_format = format; Py_SETREF(self->s_format, format);
if (prepare_s(self) < 0) { Py_DECREF(self); return NULL; } return (PyObject *)self; ret = prepare_s(self); return ret; }

static int s_clear(PyStructObject *s) { Expand Down Expand Up @@ -2202,8 +2208,9 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, {Py_tp_getset, s_getsetlist}, {Py_tp_new, Struct}, {Py_tp_init, Struct___init__}, {Py_tp_alloc, PyType_GenericAlloc}, {Py_tp_new, s_new}, {Py_tp_free, PyObject_GC_Del}, {0, 0}, }; Expand Down