diff options
Diffstat (limited to 'Objects/structseq.c')
| -rw-r--r-- | Objects/structseq.c | 86 | 
1 files changed, 60 insertions, 26 deletions
| diff --git a/Objects/structseq.c b/Objects/structseq.c index c3b9a72989..664344be6c 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -11,17 +11,20 @@ static char unnamed_fields_key[] = "n_unnamed_fields";  /* Fields with this name have only a field index, not a field name.     They are only allowed for indices < n_visible_fields. */  char *PyStructSequence_UnnamedField = "unnamed field"; +_Py_IDENTIFIER(n_sequence_fields); +_Py_IDENTIFIER(n_fields); +_Py_IDENTIFIER(n_unnamed_fields);  #define VISIBLE_SIZE(op) Py_SIZE(op)  #define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \ -                      PyDict_GetItemString((tp)->tp_dict, visible_length_key)) +                      _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields))  #define REAL_SIZE_TP(tp) PyLong_AsLong( \ -                      PyDict_GetItemString((tp)->tp_dict, real_length_key)) +                      _PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields))  #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))  #define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \ -                      PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key)) +                      _PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields))  #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op)) @@ -59,7 +62,7 @@ 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]); @@ -230,8 +233,8 @@ structseq_repr(PyStructSequence *obj)  static PyObject *  structseq_reduce(PyStructSequence* self)  { -    PyObject* tup; -    PyObject* dict; +    PyObject* tup = NULL; +    PyObject* dict = NULL;      PyObject* result;      Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;      int i; @@ -240,15 +243,12 @@ structseq_reduce(PyStructSequence* self)      n_visible_fields = VISIBLE_SIZE(self);      n_unnamed_fields = UNNAMED_FIELDS(self);      tup = PyTuple_New(n_visible_fields); -    if (!tup) { -        return NULL; -    } +    if (!tup) +        goto error;      dict = PyDict_New(); -    if (!dict) { -        Py_DECREF(tup); -        return NULL; -    } +    if (!dict) +        goto error;      for (i = 0; i < n_visible_fields; i++) {          Py_INCREF(self->ob_item[i]); @@ -257,8 +257,8 @@ structseq_reduce(PyStructSequence* self)      for (; i < n_fields; i++) {          char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; -        PyDict_SetItemString(dict, n, -                             self->ob_item[i]); +        if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0) +            goto error;      }      result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict); @@ -267,6 +267,11 @@ structseq_reduce(PyStructSequence* self)      Py_DECREF(dict);      return result; + +error: +    Py_XDECREF(tup); +    Py_XDECREF(dict); +    return NULL;  }  static PyMethodDef structseq_methods[] = { @@ -315,12 +320,13 @@ static PyTypeObject _struct_sequence_template = {      structseq_new,                              /* tp_new */  }; -void -PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) +int +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)  {      PyObject *dict;      PyMemberDef* members;      int n_members, n_unnamed_members, i, k; +    PyObject *v;  #ifdef Py_TRACE_REFS      /* if the type object was chained, unchain it first @@ -342,8 +348,10 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)      type->tp_doc = desc->doc;      members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1); -    if (members == NULL) -        return; +    if (members == NULL) { +        PyErr_NoMemory(); +        return -1; +    }      for (i = k = 0; i < n_members; ++i) {          if (desc->fields[i].name == PyStructSequence_UnnamedField) @@ -361,30 +369,56 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)      type->tp_members = members;      if (PyType_Ready(type) < 0) -        return; +        return -1;      Py_INCREF(type);      dict = type->tp_dict;  #define SET_DICT_FROM_INT(key, value)                           \      do {                                                        \ -        PyObject *v = PyLong_FromLong((long) value);            \ -        if (v != NULL) {                                        \ -            PyDict_SetItemString(dict, key, v);                 \ +        v = PyLong_FromLong((long) value);                      \ +        if (v == NULL)                                          \ +            return -1;                                          \ +        if (PyDict_SetItemString(dict, key, v) < 0) {           \              Py_DECREF(v);                                       \ +            return -1;                                          \          }                                                       \ +        Py_DECREF(v);                                           \      } while (0)      SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);      SET_DICT_FROM_INT(real_length_key, n_members);      SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); + +    return 0; +} + +void +PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) +{ +    (void)PyStructSequence_InitType2(type, desc);  }  PyTypeObject*  PyStructSequence_NewType(PyStructSequence_Desc *desc)  { -    PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); -    if (result != NULL) { -        PyStructSequence_InitType(result, desc); +    PyTypeObject *result; + +    result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); +    if (result == NULL) +        return NULL; +    if (PyStructSequence_InitType2(result, desc) < 0) { +        Py_DECREF(result); +        return NULL;      }      return result;  } + +int _PyStructSequence_Init(void) +{ +    if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL +        || _PyUnicode_FromId(&PyId_n_fields) == NULL +        || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) +        return -1; + +    return 0; +} | 
