mirror of
https://github.com/python/cpython
synced 2024-09-16 01:31:10 +00:00
bpo-42064: Move sqlite3
exceptions to global state, part 1 of 2 (GH-26745)
Also adds a test to verify the (borrowed) exceptions in `sqlite3.Connection`.
This commit is contained in:
parent
489699ca05
commit
a50e28377b
|
@ -208,6 +208,24 @@ def test_in_transaction_ro(self):
|
|||
with self.assertRaises(AttributeError):
|
||||
self.cx.in_transaction = True
|
||||
|
||||
def test_connection_exceptions(self):
|
||||
exceptions = [
|
||||
"DataError",
|
||||
"DatabaseError",
|
||||
"Error",
|
||||
"IntegrityError",
|
||||
"InterfaceError",
|
||||
"NotSupportedError",
|
||||
"OperationalError",
|
||||
"ProgrammingError",
|
||||
"Warning",
|
||||
]
|
||||
for exc in exceptions:
|
||||
with self.subTest(exc=exc):
|
||||
self.assertTrue(hasattr(self.cx, exc))
|
||||
self.assertIs(getattr(sqlite, exc), getattr(self.cx, exc))
|
||||
|
||||
|
||||
class OpenTests(unittest.TestCase):
|
||||
_sql = "create table test(id integer)"
|
||||
|
||||
|
|
|
@ -182,14 +182,15 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
|
|||
return -1;
|
||||
}
|
||||
|
||||
self->Warning = pysqlite_Warning;
|
||||
self->Error = pysqlite_Error;
|
||||
self->InterfaceError = pysqlite_InterfaceError;
|
||||
self->DatabaseError = pysqlite_DatabaseError;
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
self->Warning = state->Warning;
|
||||
self->Error = state->Error;
|
||||
self->InterfaceError = state->InterfaceError;
|
||||
self->DatabaseError = state->DatabaseError;
|
||||
self->DataError = pysqlite_DataError;
|
||||
self->OperationalError = pysqlite_OperationalError;
|
||||
self->IntegrityError = pysqlite_IntegrityError;
|
||||
self->InternalError = pysqlite_InternalError;
|
||||
self->InternalError = state->InternalError;
|
||||
self->ProgrammingError = pysqlite_ProgrammingError;
|
||||
self->NotSupportedError = pysqlite_NotSupportedError;
|
||||
|
||||
|
|
|
@ -272,7 +272,8 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
|||
PyObject* error_msg;
|
||||
|
||||
if (self->reset) {
|
||||
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
||||
PyObject *exc = self->connection->InterfaceError;
|
||||
PyErr_SetString(exc, errmsg_fetch_across_rollback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -822,7 +823,8 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
|
|||
}
|
||||
|
||||
if (self->reset) {
|
||||
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
||||
PyObject *exc = self->connection->InterfaceError;
|
||||
PyErr_SetString(exc, errmsg_fetch_across_rollback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,6 @@ module _sqlite3
|
|||
|
||||
/* static objects at module-level */
|
||||
|
||||
PyObject *pysqlite_Error = NULL;
|
||||
PyObject *pysqlite_Warning = NULL;
|
||||
PyObject *pysqlite_InterfaceError = NULL;
|
||||
PyObject *pysqlite_DatabaseError = NULL;
|
||||
PyObject *pysqlite_InternalError = NULL;
|
||||
PyObject *pysqlite_OperationalError = NULL;
|
||||
PyObject *pysqlite_ProgrammingError = NULL;
|
||||
PyObject *pysqlite_IntegrityError = NULL;
|
||||
|
@ -409,20 +404,27 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
|
|||
ADD_TYPE(module, state->RowType);
|
||||
|
||||
/*** Create DB-API Exception hierarchy */
|
||||
ADD_EXCEPTION(module, "Error", pysqlite_Error, PyExc_Exception);
|
||||
ADD_EXCEPTION(module, "Warning", pysqlite_Warning, PyExc_Exception);
|
||||
ADD_EXCEPTION(module, "Error", state->Error, PyExc_Exception);
|
||||
ADD_EXCEPTION(module, "Warning", state->Warning, PyExc_Exception);
|
||||
|
||||
/* Error subclasses */
|
||||
ADD_EXCEPTION(module, "InterfaceError", pysqlite_InterfaceError, pysqlite_Error);
|
||||
ADD_EXCEPTION(module, "DatabaseError", pysqlite_DatabaseError, pysqlite_Error);
|
||||
ADD_EXCEPTION(module, "InterfaceError", state->InterfaceError,
|
||||
state->Error);
|
||||
ADD_EXCEPTION(module, "DatabaseError", state->DatabaseError, state->Error);
|
||||
|
||||
/* pysqlite_DatabaseError subclasses */
|
||||
ADD_EXCEPTION(module, "InternalError", pysqlite_InternalError, pysqlite_DatabaseError);
|
||||
ADD_EXCEPTION(module, "OperationalError", pysqlite_OperationalError, pysqlite_DatabaseError);
|
||||
ADD_EXCEPTION(module, "ProgrammingError", pysqlite_ProgrammingError, pysqlite_DatabaseError);
|
||||
ADD_EXCEPTION(module, "IntegrityError", pysqlite_IntegrityError, pysqlite_DatabaseError);
|
||||
ADD_EXCEPTION(module, "DataError", pysqlite_DataError, pysqlite_DatabaseError);
|
||||
ADD_EXCEPTION(module, "NotSupportedError", pysqlite_NotSupportedError, pysqlite_DatabaseError);
|
||||
/* DatabaseError subclasses */
|
||||
ADD_EXCEPTION(module, "InternalError", state->InternalError,
|
||||
state->DatabaseError);
|
||||
ADD_EXCEPTION(module, "OperationalError", pysqlite_OperationalError,
|
||||
state->DatabaseError);
|
||||
ADD_EXCEPTION(module, "ProgrammingError", pysqlite_ProgrammingError,
|
||||
state->DatabaseError);
|
||||
ADD_EXCEPTION(module, "IntegrityError", pysqlite_IntegrityError,
|
||||
state->DatabaseError);
|
||||
ADD_EXCEPTION(module, "DataError", pysqlite_DataError,
|
||||
state->DatabaseError);
|
||||
ADD_EXCEPTION(module, "NotSupportedError", pysqlite_NotSupportedError,
|
||||
state->DatabaseError);
|
||||
|
||||
/* Set integer constants */
|
||||
if (add_integer_constants(module) < 0) {
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
#define MODULE_NAME "sqlite3"
|
||||
|
||||
typedef struct {
|
||||
PyObject *DatabaseError;
|
||||
PyObject *Error;
|
||||
PyObject *InterfaceError;
|
||||
PyObject *InternalError;
|
||||
PyObject *Warning;
|
||||
PyObject *lru_cache;
|
||||
PyTypeObject *ConnectionType;
|
||||
PyTypeObject *CursorType;
|
||||
|
@ -46,11 +51,6 @@ pysqlite_get_state(PyObject *Py_UNUSED(module))
|
|||
return &pysqlite_global_state;
|
||||
}
|
||||
|
||||
extern PyObject* pysqlite_Error;
|
||||
extern PyObject* pysqlite_Warning;
|
||||
extern PyObject* pysqlite_InterfaceError;
|
||||
extern PyObject* pysqlite_DatabaseError;
|
||||
extern PyObject* pysqlite_InternalError;
|
||||
extern PyObject* pysqlite_OperationalError;
|
||||
extern PyObject* pysqlite_ProgrammingError;
|
||||
extern PyObject* pysqlite_IntegrityError;
|
||||
|
|
|
@ -51,12 +51,13 @@ typedef enum {
|
|||
pysqlite_Statement *
|
||||
pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
assert(PyUnicode_Check(sql));
|
||||
Py_ssize_t size;
|
||||
const char *sql_cstr = PyUnicode_AsUTF8AndSize(sql, &size);
|
||||
if (sql_cstr == NULL) {
|
||||
PyErr_Format(pysqlite_Warning,
|
||||
"SQL is of wrong type ('%s'). Must be string.",
|
||||
PyObject *exc = connection->Warning;
|
||||
PyErr_Format(exc, "SQL is of wrong type ('%s'). Must be string.",
|
||||
Py_TYPE(sql)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -86,8 +87,8 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
|||
}
|
||||
|
||||
if (pysqlite_check_remaining_sql(tail)) {
|
||||
PyErr_SetString(pysqlite_Warning,
|
||||
"You can only execute one statement at a time.");
|
||||
PyObject *exc = connection->Warning;
|
||||
PyErr_SetString(exc, "You can only execute one statement at a time.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -110,7 +111,6 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
|||
break;
|
||||
}
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement,
|
||||
state->StatementType);
|
||||
if (self == NULL) {
|
||||
|
@ -288,7 +288,9 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
|
|||
|
||||
if (rc != SQLITE_OK) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
|
||||
PyErr_Format(state->InterfaceError,
|
||||
"Error binding parameter %d - "
|
||||
"probably unsupported type.", i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -342,7 +344,9 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
|
|||
|
||||
if (rc != SQLITE_OK) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
|
||||
PyErr_Format(state->InterfaceError,
|
||||
"Error binding parameter :%s - "
|
||||
"probably unsupported type.", binding_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ pysqlite_step(sqlite3_stmt *statement)
|
|||
int
|
||||
_pysqlite_seterror(sqlite3 *db)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
int errorcode = sqlite3_errcode(db);
|
||||
|
||||
switch (errorcode)
|
||||
|
@ -52,7 +53,7 @@ _pysqlite_seterror(sqlite3 *db)
|
|||
break;
|
||||
case SQLITE_INTERNAL:
|
||||
case SQLITE_NOTFOUND:
|
||||
PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db));
|
||||
PyErr_SetString(state->InternalError, sqlite3_errmsg(db));
|
||||
break;
|
||||
case SQLITE_NOMEM:
|
||||
(void)PyErr_NoMemory();
|
||||
|
@ -73,7 +74,7 @@ _pysqlite_seterror(sqlite3 *db)
|
|||
PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db));
|
||||
break;
|
||||
case SQLITE_CORRUPT:
|
||||
PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
|
||||
PyErr_SetString(state->DatabaseError, sqlite3_errmsg(db));
|
||||
break;
|
||||
case SQLITE_TOOBIG:
|
||||
PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db));
|
||||
|
@ -86,7 +87,7 @@ _pysqlite_seterror(sqlite3 *db)
|
|||
PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db));
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
|
||||
PyErr_SetString(state->DatabaseError, sqlite3_errmsg(db));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,11 +49,6 @@ Modules/_io/_iomodule.h - _PyIO_str_write -
|
|||
Modules/_io/_iomodule.h - _PyIO_empty_str -
|
||||
Modules/_io/_iomodule.h - _PyIO_empty_bytes -
|
||||
Modules/_multiprocessing/multiprocessing.h - _PyMp_SemLockType -
|
||||
Modules/_sqlite/module.c - pysqlite_Error -
|
||||
Modules/_sqlite/module.c - pysqlite_Warning -
|
||||
Modules/_sqlite/module.c - pysqlite_InterfaceError -
|
||||
Modules/_sqlite/module.c - pysqlite_DatabaseError -
|
||||
Modules/_sqlite/module.c - pysqlite_InternalError -
|
||||
Modules/_sqlite/module.c - pysqlite_OperationalError -
|
||||
Modules/_sqlite/module.c - pysqlite_ProgrammingError -
|
||||
Modules/_sqlite/module.c - pysqlite_IntegrityError -
|
||||
|
@ -2371,11 +2366,6 @@ Modules/_ctypes/_ctypes.c - PyExc_ArgError -
|
|||
Modules/_cursesmodule.c - PyCursesError -
|
||||
Modules/_decimal/_decimal.c - DecimalException -
|
||||
Modules/_queuemodule.c - EmptyError -
|
||||
Modules/_sqlite/module.h - pysqlite_Error -
|
||||
Modules/_sqlite/module.h - pysqlite_Warning -
|
||||
Modules/_sqlite/module.h - pysqlite_InterfaceError -
|
||||
Modules/_sqlite/module.h - pysqlite_DatabaseError -
|
||||
Modules/_sqlite/module.h - pysqlite_InternalError -
|
||||
Modules/_sqlite/module.h - pysqlite_OperationalError -
|
||||
Modules/_sqlite/module.h - pysqlite_ProgrammingError -
|
||||
Modules/_sqlite/module.h - pysqlite_IntegrityError -
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Reference in a new issue