summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite/microprotocols.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_sqlite/microprotocols.c')
-rw-r--r--Modules/_sqlite/microprotocols.c74
1 files changed, 44 insertions, 30 deletions
diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c
index 3d01872..c23b09f 100644
--- a/Modules/_sqlite/microprotocols.c
+++ b/Modules/_sqlite/microprotocols.c
@@ -75,7 +75,9 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
PyObject *
pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
{
- PyObject *adapter, *key;
+ _Py_IDENTIFIER(__adapt__);
+ _Py_IDENTIFIER(__conform__);
+ PyObject *adapter, *key, *adapted;
/* we don't check for exact type conformance as specified in PEP 246
because the pysqlite_PrepareProtocolType type is abstract and there is no
@@ -86,48 +88,60 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
if (!key) {
return NULL;
}
- adapter = PyDict_GetItem(psyco_adapters, key);
+ adapter = PyDict_GetItemWithError(psyco_adapters, key);
Py_DECREF(key);
if (adapter) {
- PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ Py_INCREF(adapter);
+ adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ Py_DECREF(adapter);
return adapted;
}
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
- /* try to have the protocol adapt this object*/
- if (PyObject_HasAttrString(proto, "__adapt__")) {
- _Py_IDENTIFIER(__adapt__);
- PyObject *adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj);
-
- if (adapted) {
- if (adapted != Py_None) {
- return adapted;
- } else {
- Py_DECREF(adapted);
- }
- }
+ /* try to have the protocol adapt this object */
+ if (_PyObject_LookupAttrId(proto, &PyId___adapt__, &adapter) < 0) {
+ return NULL;
+ }
+ if (adapter) {
+ adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ Py_DECREF(adapter);
- if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
- return NULL;
+ if (adapted == Py_None) {
+ Py_DECREF(adapted);
+ }
+ else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) {
+ return adapted;
+ }
+ else {
+ PyErr_Clear();
+ }
}
/* and finally try to have the object adapt itself */
- if (PyObject_HasAttrString(obj, "__conform__")) {
- _Py_IDENTIFIER(__conform__);
- PyObject *adapted = _PyObject_CallMethodId(obj, &PyId___conform__,"O", proto);
-
- if (adapted) {
- if (adapted != Py_None) {
- return adapted;
- } else {
- Py_DECREF(adapted);
- }
- }
+ if (_PyObject_LookupAttrId(obj, &PyId___conform__, &adapter) < 0) {
+ return NULL;
+ }
+ if (adapter) {
+ adapted = PyObject_CallFunctionObjArgs(adapter, proto, NULL);
+ Py_DECREF(adapter);
- if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
- return NULL;
+ if (adapted == Py_None) {
+ Py_DECREF(adapted);
+ }
+ else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) {
+ return adapted;
+ }
+ else {
+ PyErr_Clear();
}
}
+ if (alt) {
+ Py_INCREF(alt);
+ return alt;
+ }
/* else set the right exception and return NULL */
PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
return NULL;