diff Objects/structseq.c @ 84793:fc718c177ee6

Issue #18520: Add a new PyStructSequence_InitType2() function, same than PyStructSequence_InitType() except that it has a return value (0 on success, -1 on error). * PyStructSequence_InitType2() now raises MemoryError on memory allocation failure * Fix also some calls to PyDict_SetItemString(): handle error
author Victor Stinner <victor.stinner@gmail.com>
date Mon, 22 Jul 2013 22:24:54 +0200
parents 7b81a535ad14
children
line wrap: on
line diff
--- a/Objects/structseq.c	Mon Jul 22 13:08:21 2013 -0500
+++ b/Objects/structseq.c	Mon Jul 22 22:24:54 2013 +0200
@@ -320,12 +320,13 @@
     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
@@ -347,8 +348,10 @@
     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)
@@ -366,22 +369,33 @@
     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*
@@ -390,8 +404,11 @@
     PyTypeObject *result;
 
     result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
-    if (result != NULL) {
-        PyStructSequence_InitType(result, desc);
+    if (result == NULL)
+        return NULL;
+    if (PyStructSequence_InitType2(result, desc) < 0) {
+        Py_DECREF(result);
+        return NULL;
     }
     return result;
 }