Guard from failed keys creation during adaptation

This commit is contained in:
Daniele Varrazzo 2012-03-04 04:40:44 +00:00
parent 18085201c8
commit dc4c3d3143

View File

@ -78,9 +78,9 @@ exit:
/* Check if one of `obj` superclasses has an adapter for `proto`. /* Check if one of `obj` superclasses has an adapter for `proto`.
* *
* If it does, return a *borrowed reference* to the adapter, else NULL. * If it does, return a *borrowed reference* to the adapter, else to None.
*/ */
static PyObject * BORROWED static PyObject *
_get_superclass_adapter(PyObject *obj, PyObject *proto) _get_superclass_adapter(PyObject *obj, PyObject *proto)
{ {
PyTypeObject *type; PyTypeObject *type;
@ -95,14 +95,14 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto)
#endif #endif
type->tp_mro)) { type->tp_mro)) {
/* has no mro */ /* has no mro */
return NULL; return Py_None;
} }
/* Walk the mro from the most specific subclass. */ /* Walk the mro from the most specific subclass. */
mro = type->tp_mro; mro = type->tp_mro;
for (i = 1, ii = PyTuple_GET_SIZE(mro); i < ii; ++i) { for (i = 1, ii = PyTuple_GET_SIZE(mro); i < ii; ++i) {
st = PyTuple_GET_ITEM(mro, i); st = PyTuple_GET_ITEM(mro, i);
key = PyTuple_Pack(2, st, proto); if (!(key = PyTuple_Pack(2, st, proto))) { return NULL; }
adapter = PyDict_GetItem(psyco_adapters, key); adapter = PyDict_GetItem(psyco_adapters, key);
Py_DECREF(key); Py_DECREF(key);
@ -125,7 +125,7 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto)
return adapter; return adapter;
} }
} }
return NULL; return Py_None;
} }
@ -145,7 +145,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
Py_TYPE(obj)->tp_name); Py_TYPE(obj)->tp_name);
/* look for an adapter in the registry */ /* look for an adapter in the registry */
key = PyTuple_Pack(2, Py_TYPE(obj), proto); if (!(key = PyTuple_Pack(2, Py_TYPE(obj), proto))) { return NULL; }
adapter = PyDict_GetItem(psyco_adapters, key); adapter = PyDict_GetItem(psyco_adapters, key);
Py_DECREF(key); Py_DECREF(key);
if (adapter) { if (adapter) {
@ -154,7 +154,10 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
} }
/* Check if a superclass can be adapted and use the same adapter. */ /* Check if a superclass can be adapted and use the same adapter. */
if (NULL != (adapter = _get_superclass_adapter(obj, proto))) { if (!(adapter = _get_superclass_adapter(obj, proto))) {
return NULL;
}
if (Py_None != adapter) {
adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL); adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
return adapted; return adapted;
} }