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
This commit is contained in:
Victor Stinner 2013-07-22 22:24:54 +02:00
parent 2a545099f7
commit 1c8f059019
17 changed files with 117 additions and 54 deletions

View file

@ -320,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
@ -347,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)
@ -366,22 +369,33 @@ 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*
@ -390,8 +404,11 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
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;
}