bpo-42064: Move `sqlite3` exceptions to global state, part 2 of 2 by erlend-aasland · Pull Request #26884 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions Modules/_sqlite/connection.c
30 changes: 21 additions & 9 deletions Modules/_sqlite/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,12 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self)
PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
colname , text);
error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace");

PyObject *exc = self->connection->OperationalError;
if (!error_msg) {
PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8");
PyErr_SetString(exc, "Could not decode to UTF-8");
} else {
PyErr_SetObject(pysqlite_OperationalError, error_msg);
PyErr_SetObject(exc, error_msg);
Py_DECREF(error_msg);
}
}
Expand Down Expand Up @@ -401,18 +403,23 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self)
*/
static int check_cursor(pysqlite_Cursor* cur)
{
pysqlite_state *state = pysqlite_get_state(NULL);

if (!cur->initialized) {
PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called.");
PyErr_SetString(state->ProgrammingError,
"Base Cursor.__init__ not called.");
return 0;
}

if (cur->closed) {
PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor.");
PyErr_SetString(state->ProgrammingError,
"Cannot operate on a closed cursor.");
return 0;
}

if (cur->locked) {
PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed.");
PyErr_SetString(state->ProgrammingError,
"Recursive use of cursors not allowed.");
return 0;
}

Expand Down Expand Up @@ -588,7 +595,8 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
}

if (pysqlite_build_row_cast_map(self) != 0) {
_PyErr_FormatFromCause(pysqlite_OperationalError, "Error while building row_cast_map");
_PyErr_FormatFromCause(self->connection->OperationalError,
"Error while building row_cast_map");
goto error;
}

Expand Down Expand Up @@ -641,7 +649,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation

if (rc == SQLITE_ROW) {
if (multiple) {
PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements.");
PyErr_SetString(self->connection->ProgrammingError,
"executemany() can only execute DML "
"statements.");
goto error;
}

Expand Down Expand Up @@ -745,7 +755,8 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
int max_length = sqlite3_limit(self->connection->db,
SQLITE_LIMIT_LENGTH, -1);
if (sql_len >= max_length) {
PyErr_SetString(pysqlite_DataError, "query string is too large");
PyErr_SetString(self->connection->DataError,
"query string is too large");
return NULL;
}
} else {
Expand Down Expand Up @@ -1018,7 +1029,8 @@ pysqlite_cursor_close_impl(pysqlite_Cursor *self)
/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/
{
if (!self->connection) {
PyErr_SetString(pysqlite_ProgrammingError,
pysqlite_state *state = pysqlite_get_state(NULL);
PyErr_SetString(state->ProgrammingError,
"Base Cursor.__init__ not called.");
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion Modules/_sqlite/microprotocols.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
return Py_NewRef(alt);
}
/* else set the right exception and return NULL */
PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
pysqlite_state *state = pysqlite_get_state(NULL);
PyErr_SetString(state->ProgrammingError, "can't adapt");
return NULL;
}
55 changes: 19 additions & 36 deletions Modules/_sqlite/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ module _sqlite3
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/

/* static objects at module-level */

PyObject *pysqlite_OperationalError = NULL;
PyObject *pysqlite_ProgrammingError = NULL;
PyObject *pysqlite_IntegrityError = NULL;
PyObject *pysqlite_DataError = NULL;
PyObject *pysqlite_NotSupportedError = NULL;

PyObject* _pysqlite_converters = NULL;
int _pysqlite_enable_callback_tracebacks = 0;
int pysqlite_BaseTypeAdapted = 0;
Expand Down Expand Up @@ -137,7 +130,8 @@ pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable)
rc = sqlite3_enable_shared_cache(do_enable);

if (rc != SQLITE_OK) {
PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed");
pysqlite_state *state = pysqlite_get_state(module);
PyErr_SetString(state->OperationalError, "Changing the shared_cache flag failed");
return NULL;
} else {
Py_RETURN_NONE;
Expand Down Expand Up @@ -357,17 +351,13 @@ do { \
} \
} while (0)

#define ADD_EXCEPTION(module, name, exc, base) \
do { \
exc = PyErr_NewException(MODULE_NAME "." name, base, NULL); \
if (!exc) { \
goto error; \
} \
int res = PyModule_AddObjectRef(module, name, exc); \
Py_DECREF(exc); \
if (res < 0) { \
goto error; \
} \
#define ADD_EXCEPTION(module, state, exc, base) \
do { \
state->exc = PyErr_NewException(MODULE_NAME "." #exc, base, NULL); \
if (state->exc == NULL) { \
goto error; \
} \
ADD_TYPE(module, (PyTypeObject *)state->exc); \
} while (0)

PyMODINIT_FUNC PyInit__sqlite3(void)
Expand Down Expand Up @@ -404,27 +394,20 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
ADD_TYPE(module, state->RowType);

/*** Create DB-API Exception hierarchy */
ADD_EXCEPTION(module, "Error", state->Error, PyExc_Exception);
ADD_EXCEPTION(module, "Warning", state->Warning, PyExc_Exception);
ADD_EXCEPTION(module, state, Error, PyExc_Exception);
ADD_EXCEPTION(module, state, Warning, PyExc_Exception);

/* Error subclasses */
ADD_EXCEPTION(module, "InterfaceError", state->InterfaceError,
state->Error);
ADD_EXCEPTION(module, "DatabaseError", state->DatabaseError, state->Error);
ADD_EXCEPTION(module, state, InterfaceError, state->Error);
ADD_EXCEPTION(module, state, DatabaseError, state->Error);

/* 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);
ADD_EXCEPTION(module, state, InternalError, state->DatabaseError);
ADD_EXCEPTION(module, state, OperationalError, state->DatabaseError);
ADD_EXCEPTION(module, state, ProgrammingError, state->DatabaseError);
ADD_EXCEPTION(module, state, IntegrityError, state->DatabaseError);
ADD_EXCEPTION(module, state, DataError, state->DatabaseError);
ADD_EXCEPTION(module, state, NotSupportedError, state->DatabaseError);

/* Set integer constants */
if (add_integer_constants(module) < 0) {
Expand Down
13 changes: 7 additions & 6 deletions Modules/_sqlite/module.h
Loading