@@ -70,6 +70,7 @@ typedef struct {
7070 formatcode * s_codes ;
7171 PyObject * s_format ;
7272 PyObject * weakreflist ; /* List of weak references */
73+ bool init_called ;
7374} PyStructObject ;
7475
7576#define PyStructObject_CAST (op ) ((PyStructObject *)(op))
@@ -1757,30 +1758,61 @@ prepare_s(PyStructObject *self)
17571758 return -1 ;
17581759}
17591760
1761+ static int
1762+ actual___init___impl (PyStructObject * self , PyObject * format )
1763+ {
1764+ if (PyUnicode_Check (format )) {
1765+ format = PyUnicode_AsASCIIString (format );
1766+ if (format == NULL )
1767+ return -1 ;
1768+ }
1769+ else {
1770+ Py_INCREF (format );
1771+ }
1772+ if (!PyBytes_Check (format )) {
1773+ Py_DECREF (format );
1774+ PyErr_Format (PyExc_TypeError ,
1775+ "Struct() argument 1 must be a str or bytes object, "
1776+ "not %.200s" ,
1777+ _PyType_Name (Py_TYPE (format )));
1778+ return -1 ;
1779+ }
1780+ Py_SETREF (self -> s_format , format );
1781+ if (prepare_s (self )) {
1782+ return -1 ;
1783+ }
1784+ return 0 ;
1785+ }
1786+
17601787static PyObject *
17611788s_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
17621789{
1763- PyObject * self ;
1790+ PyStructObject * self ;
17641791
1765- if (PyTuple_GET_SIZE (args ) != 1
1792+ if (( PyTuple_GET_SIZE (args ) != 1 || kwds )
17661793 && PyErr_WarnEx (PyExc_DeprecationWarning ,
1767- "Struct() .__new__() has one required argument" , 1 ))
1794+ "Struct.__new__() has one positional argument" , 1 ))
17681795 {
17691796 return NULL ;
17701797 }
17711798 assert (type != NULL );
17721799 allocfunc alloc_func = PyType_GetSlot (type , Py_tp_alloc );
17731800 assert (alloc_func != NULL );
1774-
1775- self = alloc_func (type , 0 );
1801+ self = (PyStructObject * )alloc_func (type , 0 );
17761802 if (self != NULL ) {
1777- PyStructObject * s = (PyStructObject * )self ;
1778- s -> s_format = Py_NewRef (Py_None );
1779- s -> s_codes = NULL ;
1780- s -> s_size = -1 ;
1781- s -> s_len = -1 ;
1803+ self -> s_format = Py_NewRef (Py_None );
1804+ self -> s_codes = NULL ;
1805+ self -> s_size = -1 ;
1806+ self -> s_len = -1 ;
1807+ self -> init_called = false;
1808+ if (PyTuple_GET_SIZE (args ) > 0 ) {
1809+ if (actual___init___impl (self , PyTuple_GET_ITEM (args , 0 ))) {
1810+ Py_DECREF (self );
1811+ return NULL ;
1812+ }
1813+ }
17821814 }
1783- return self ;
1815+ return ( PyObject * ) self ;
17841816}
17851817
17861818/*[clinic input]
@@ -1800,37 +1832,21 @@ static int
18001832Struct___init___impl (PyStructObject * self , PyObject * format )
18011833/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
18021834{
1803- int ret = 0 ;
1804-
1805- if (self -> s_codes
1835+ if (!self -> init_called ) {
1836+ if (!self -> s_codes && actual___init___impl (self , format )) {
1837+ return -1 ;
1838+ }
1839+ self -> init_called = true;
1840+ return 0 ;
1841+ }
1842+ if ((self -> s_codes && self -> init_called )
18061843 && PyErr_WarnEx (PyExc_DeprecationWarning ,
18071844 ("Explicit call of __init__() on "
18081845 "initialized Struct() is deprecated" ), 1 ))
18091846 {
18101847 return -1 ;
18111848 }
1812- if (PyUnicode_Check (format )) {
1813- format = PyUnicode_AsASCIIString (format );
1814- if (format == NULL )
1815- return -1 ;
1816- }
1817- else {
1818- Py_INCREF (format );
1819- }
1820-
1821- if (!PyBytes_Check (format )) {
1822- Py_DECREF (format );
1823- PyErr_Format (PyExc_TypeError ,
1824- "Struct() argument 1 must be a str or bytes object, "
1825- "not %.200s" ,
1826- _PyType_Name (Py_TYPE (format )));
1827- return -1 ;
1828- }
1829-
1830- Py_SETREF (self -> s_format , format );
1831-
1832- ret = prepare_s (self );
1833- return ret ;
1849+ return actual___init___impl (self , format );
18341850}
18351851
18361852static int
@@ -2473,9 +2489,7 @@ static PyType_Slot PyStructType_slots[] = {
24732489 {Py_tp_members , s_members },
24742490 {Py_tp_getset , s_getsetlist },
24752491 {Py_tp_init , Struct___init__ },
2476- {Py_tp_alloc , PyType_GenericAlloc },
24772492 {Py_tp_new , s_new },
2478- {Py_tp_free , PyObject_GC_Del },
24792493 {0 , 0 },
24802494};
24812495
0 commit comments