Check errors in module typecasters init

This commit is contained in:
Daniele Varrazzo 2012-02-23 19:20:51 +00:00
parent ff61cf25b6
commit 08fbd86495
2 changed files with 82 additions and 34 deletions

View File

@ -52,22 +52,28 @@ microprotocols_init(PyObject *dict)
} }
/* microprotocols_add - add a reverse type-caster to the dictionary */ /* microprotocols_add - add a reverse type-caster to the dictionary
*
* Return 0 on success, else -1 and set an exception.
*/
int int
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
{ {
PyObject *key; PyObject *key = NULL;
int rv = -1;
if (proto == NULL) proto = (PyObject*)&isqlquoteType; if (proto == NULL) proto = (PyObject*)&isqlquoteType;
Dprintf("microprotocols_add: cast %p for (%s, ?)", cast, type->tp_name); Dprintf("microprotocols_add: cast %p for (%s, ?)", cast, type->tp_name);
key = PyTuple_Pack(2, (PyObject*)type, proto); if (!(key = PyTuple_Pack(2, (PyObject*)type, proto))) { goto exit; }
PyDict_SetItem(psyco_adapters, key, cast); if (0 != PyDict_SetItem(psyco_adapters, key, cast)) { goto exit; }
Py_DECREF(key);
return 0; rv = 0;
exit:
Py_XDECREF(key);
return rv;
} }
/* Check if one of `obj` superclasses has an adapter for `proto`. /* Check if one of `obj` superclasses has an adapter for `proto`.

View File

@ -182,66 +182,108 @@ psyco_register_type(PyObject *self, PyObject *args)
} }
/* default adapters */ /* Initialize the default adapters map
*
static void * Return 0 on success, else -1 and set an exception.
*/
static int
psyco_adapters_init(PyObject *mod) psyco_adapters_init(PyObject *mod)
{ {
PyObject *call; PyObject *call = NULL;
int rv = -1;
microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType); if (0 != microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
goto exit;
}
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType); if (0 != microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) {
goto exit;
}
#endif #endif
microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType); if (0 != microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType); goto exit;
}
if (0 != microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) {
goto exit;
}
/* strings */ /* strings */
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType); if (0 != microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) {
goto exit;
}
#endif #endif
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType); if (0 != microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
goto exit;
}
/* binary */ /* binary */
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType); if (0 != microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) {
goto exit;
}
#else #else
microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType); if (0 != microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
goto exit;
}
#endif #endif
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6 #if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6
microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType); if (0 != microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
goto exit;
}
#endif #endif
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7 #if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7
microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType); if (0 != microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) {
goto exit;
}
#endif #endif
microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType); if (0 != microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) {
goto exit;
}
/* the module has already been initialized, so we can obtain the callable /* the module has already been initialized, so we can obtain the callable
objects directly from its dictionary :) */ objects directly from its dictionary :) */
call = PyMapping_GetItemString(mod, "DateFromPy"); if (!(call = PyMapping_GetItemString(mod, "DateFromPy"))) { goto exit; }
microprotocols_add(PyDateTimeAPI->DateType, NULL, call); if (0 != microprotocols_add(PyDateTimeAPI->DateType, NULL, call)) { goto exit; }
call = PyMapping_GetItemString(mod, "TimeFromPy"); Py_CLEAR(call);
microprotocols_add(PyDateTimeAPI->TimeType, NULL, call);
call = PyMapping_GetItemString(mod, "TimestampFromPy"); if (!(call = PyMapping_GetItemString(mod, "TimeFromPy"))) { goto exit; }
microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call); if (0 != microprotocols_add(PyDateTimeAPI->TimeType, NULL, call)) { goto exit; }
call = PyMapping_GetItemString(mod, "IntervalFromPy"); Py_CLEAR(call);
microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call);
if (!(call = PyMapping_GetItemString(mod, "TimestampFromPy"))) { goto exit; }
if (0 != microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call)) { goto exit; }
Py_CLEAR(call);
if (!(call = PyMapping_GetItemString(mod, "IntervalFromPy"))) { goto exit; }
if (0 != microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call)) { goto exit; }
Py_CLEAR(call);
#ifdef HAVE_MXDATETIME #ifdef HAVE_MXDATETIME
/* as above, we use the callable objects from the psycopg module */ /* as above, we use the callable objects from the psycopg module */
if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) { if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) {
microprotocols_add(mxDateTime.DateTime_Type, NULL, call); if (0 != microprotocols_add(mxDateTime.DateTime_Type, NULL, call)) { goto exit; }
Py_CLEAR(call);
/* if we found the above, we have this too. */ /* if we found the above, we have this too. */
call = PyMapping_GetItemString(mod, "TimeFromMx"); if (!(call = PyMapping_GetItemString(mod, "TimeFromMx"))) { goto exit; }
microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call); if (0 != microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call)) { goto exit; }
Py_CLEAR(call);
} }
else { else {
PyErr_Clear(); PyErr_Clear();
} }
#endif #endif
/* Success! */
rv = 0;
exit:
Py_XDECREF(call);
return rv;
} }
/* psyco_encodings_fill /* psyco_encodings_fill
@ -960,7 +1002,7 @@ INIT_MODULE(_psycopg)(void)
/* initialize microprotocols layer */ /* initialize microprotocols layer */
microprotocols_init(dict); microprotocols_init(dict);
psyco_adapters_init(dict); if (0 != psyco_adapters_init(dict)) { goto exit; }
/* create a standard set of exceptions and add them to the module's dict */ /* create a standard set of exceptions and add them to the module's dict */
if (0 != psyco_errors_init()) { goto exit; } if (0 != psyco_errors_init()) { goto exit; }