mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-32788: Better error handling in sqlite3. (GH-3723)
Propagate unexpected errors (like MemoryError and KeyboardInterrupt) to user.
This commit is contained in:
parent
dffccc6b59
commit
fc662ac332
7 changed files with 154 additions and 122 deletions
|
|
@ -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);
|
||||
/* 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 (adapted) {
|
||||
if (adapted != Py_None) {
|
||||
return adapted;
|
||||
} else {
|
||||
Py_DECREF(adapted);
|
||||
}
|
||||
if (adapted == Py_None) {
|
||||
Py_DECREF(adapted);
|
||||
}
|
||||
else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) {
|
||||
return adapted;
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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 (_PyObject_LookupAttrId(obj, &PyId___conform__, &adapter) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (adapter) {
|
||||
adapted = PyObject_CallFunctionObjArgs(adapter, proto, NULL);
|
||||
Py_DECREF(adapter);
|
||||
|
||||
if (adapted) {
|
||||
if (adapted != Py_None) {
|
||||
return adapted;
|
||||
} else {
|
||||
Py_DECREF(adapted);
|
||||
}
|
||||
if (adapted == Py_None) {
|
||||
Py_DECREF(adapted);
|
||||
}
|
||||
|
||||
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue