@@ -1635,8 +1635,12 @@ prepare_s(PyStructObject *self, PyObject *format)
16351635
16361636 _structmodulestate * state = get_struct_state_structinst (self );
16371637
1638- fmt = PyBytes_AS_STRING (format );
1639- if (strlen (fmt ) != (size_t )PyBytes_GET_SIZE (format )) {
1638+ if (!PyUnicode_IS_ASCII (format )) {
1639+ PyErr_SetString (PyExc_ValueError , "non-ASCII character in struct format" );
1640+ return -1 ;
1641+ }
1642+ fmt = (const char * )PyUnicode_1BYTE_DATA (format );
1643+ if (strlen (fmt ) != (size_t )PyUnicode_GET_LENGTH (format )) {
16401644 PyErr_SetString (state -> StructError ,
16411645 "embedded null character" );
16421646 return -1 ;
@@ -1780,19 +1784,21 @@ static int
17801784set_format (PyStructObject * self , PyObject * format )
17811785{
17821786 if (PyUnicode_Check (format )) {
1783- format = PyUnicode_AsASCIIString (format );
1784- if (format == NULL )
1785- return -1 ;
1787+ format = PyUnicode_FromObject (format );
17861788 }
17871789 else if (PyBytes_Check (format )) {
1788- Py_INCREF (format );
1790+ format = PyUnicode_DecodeASCII (PyBytes_AS_STRING (format ),
1791+ PyBytes_GET_SIZE (format ), "surrogateescape" );
17891792 }
17901793 else {
17911794 PyErr_Format (PyExc_TypeError ,
17921795 "Struct() argument 1 must be a str or bytes object, "
17931796 "not %T" , format );
17941797 return -1 ;
17951798 }
1799+ if (format == NULL ) {
1800+ return -1 ;
1801+ }
17961802 if (prepare_s (self , format )) {
17971803 Py_DECREF (format );
17981804 return -1 ;
@@ -1821,7 +1827,7 @@ Struct_impl(PyTypeObject *type, PyObject *format)
18211827 if (self == NULL ) {
18221828 return NULL ;
18231829 }
1824- self -> s_format = Py_NewRef ( Py_None ) ;
1830+ self -> s_format = NULL ;
18251831 self -> s_codes = NULL ;
18261832 self -> s_size = -1 ;
18271833 self -> s_len = -1 ;
@@ -1878,7 +1884,7 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
18781884 if (self == NULL ) {
18791885 return NULL ;
18801886 }
1881- self -> s_format = Py_NewRef ( Py_None ) ;
1887+ self -> s_format = NULL ;
18821888 self -> s_codes = NULL ;
18831889 self -> s_size = -1 ;
18841890 self -> s_len = -1 ;
@@ -1892,7 +1898,7 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
18921898 return NULL ;
18931899 }
18941900 PyObject * exc = PyErr_GetRaisedException ();
1895- Py_SETREF (self -> s_format , Py_NewRef ( Py_None ) );
1901+ Py_CLEAR (self -> s_format );
18961902 if (PyErr_WarnFormat (PyExc_DeprecationWarning , 1 ,
18971903 "Invalid 'format' argument for Struct.__new__(): %S" , exc ))
18981904 {
@@ -1910,8 +1916,8 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19101916static bool
19111917same_format (PyStructObject * s , PyObject * format )
19121918{
1913- Py_ssize_t size = PyBytes_GET_SIZE (s -> s_format );
1914- const void * data = PyBytes_AS_STRING (s -> s_format );
1919+ Py_ssize_t size = PyUnicode_GET_LENGTH (s -> s_format );
1920+ const void * data = PyUnicode_1BYTE_DATA (s -> s_format );
19151921 if (PyUnicode_Check (format ) && PyUnicode_IS_ASCII (format )) {
19161922 return PyUnicode_GET_LENGTH (format ) == size
19171923 && memcmp (PyUnicode_1BYTE_DATA (format ), data , size ) == 0 ;
@@ -1938,7 +1944,7 @@ static int
19381944Struct___init___impl (PyStructObject * self , PyObject * format )
19391945/*[clinic end generated code: output=b8e80862444e92d0 input=1af78a5f57d82cec]*/
19401946{
1941- if (self -> s_format == Py_None ) {
1947+ if (self -> s_format == NULL ) {
19421948 if (set_format (self , format ) < 0 ) {
19431949 return -1 ;
19441950 }
@@ -1965,7 +1971,7 @@ s_init(PyObject *self, PyObject *args, PyObject *kwargs)
19651971{
19661972 if (!((PyStructObject * )self )-> init_called
19671973 && Py_TYPE (self )-> tp_init == s_init
1968- && ((PyStructObject * )self )-> s_format != Py_None )
1974+ && ((PyStructObject * )self )-> s_format != NULL )
19691975 {
19701976 /* Struct.__init__() was called implicitly.
19711977 * __new__() already did all the work. */
@@ -2508,22 +2514,6 @@ Struct_pack_into_impl(PyStructObject *self, Py_buffer *buffer,
25082514 Py_RETURN_NONE ;
25092515}
25102516
2511- static PyObject *
2512- s_get_format (PyObject * op , void * Py_UNUSED (closure ))
2513- {
2514- PyStructObject * self = PyStructObject_CAST (op );
2515- ENSURE_STRUCT_IS_READY (self );
2516- return PyUnicode_FromStringAndSize (PyBytes_AS_STRING (self -> s_format ),
2517- PyBytes_GET_SIZE (self -> s_format ));
2518- }
2519-
2520- static PyObject *
2521- s_get_size (PyObject * op , void * Py_UNUSED (closure ))
2522- {
2523- PyStructObject * self = PyStructObject_CAST (op );
2524- return PyLong_FromSsize_t (self -> s_size );
2525- }
2526-
25272517/*[clinic input]
25282518Struct.__sizeof__
25292519[clinic start generated code]*/
@@ -2545,14 +2535,7 @@ s_repr(PyObject *op)
25452535{
25462536 PyStructObject * self = PyStructObject_CAST (op );
25472537 ENSURE_STRUCT_IS_READY (self );
2548- PyObject * fmt = PyUnicode_FromStringAndSize (
2549- PyBytes_AS_STRING (self -> s_format ), PyBytes_GET_SIZE (self -> s_format ));
2550- if (fmt == NULL ) {
2551- return NULL ;
2552- }
2553- PyObject * s = PyUnicode_FromFormat ("%s(%R)" , _PyType_Name (Py_TYPE (self )), fmt );
2554- Py_DECREF (fmt );
2555- return s ;
2538+ return PyUnicode_FromFormat ("%s(%R)" , _PyType_Name (Py_TYPE (self )), self -> s_format );
25562539}
25572540
25582541/* List of functions */
@@ -2569,15 +2552,13 @@ static struct PyMethodDef s_methods[] = {
25692552
25702553static PyMemberDef s_members [] = {
25712554 {"__weaklistoffset__" , Py_T_PYSSIZET , offsetof(PyStructObject , weakreflist ), Py_READONLY },
2555+ {"format" , Py_T_OBJECT_EX , offsetof(PyStructObject , s_format ),
2556+ Py_READONLY , PyDoc_STR ("struct format string" )},
2557+ {"size" , Py_T_PYSSIZET , offsetof(PyStructObject , s_size ), Py_READONLY ,
2558+ PyDoc_STR ("struct size in bytes" )},
25722559 {NULL } /* sentinel */
25732560};
25742561
2575- static PyGetSetDef s_getsetlist [] = {
2576- {"format" , s_get_format , NULL , PyDoc_STR ("struct format string" ), NULL },
2577- {"size" , s_get_size , NULL , PyDoc_STR ("struct size in bytes" ), NULL },
2578- {NULL } /* sentinel */
2579- };
2580-
25812562static PyType_Slot PyStructType_slots [] = {
25822563 {Py_tp_dealloc , s_dealloc },
25832564 {Py_tp_getattro , PyObject_GenericGetAttr },
@@ -2588,7 +2569,6 @@ static PyType_Slot PyStructType_slots[] = {
25882569 {Py_tp_clear , s_clear },
25892570 {Py_tp_methods , s_methods },
25902571 {Py_tp_members , s_members },
2591- {Py_tp_getset , s_getsetlist },
25922572 {Py_tp_init , s_init },
25932573 {Py_tp_new , s_new },
25942574 {0 , 0 },
0 commit comments