CPython issue (assertion): python/cpython#146090
Two bugs in _sqlite/connection.c:
-
Assertion failure (line 2201): When
sqlite3_create_collation_v2()fails withSQLITE_BUSY, error cleanup callsfree_callback_context(ctx)directly — butctxhasrefcount=1. The function assertsctx->refcount == 0→ crash in debug builds. -
Missing PyErr_NoMemory (line 1061):
create_callback_contextreturns NULL without exception whenPyMem_Mallocfails. All 7 callers propagate NULL →SystemError.
- Use
decref_callback_context(ctx)instead offree_callback_context(ctx)at line 2201. - Add
if (ctx == NULL) { return (callback_context *)PyErr_NoMemory(); }.
import sqlite3
conn = sqlite3.connect(":memory:")
conn.create_collation("mycoll", lambda a, b: (a > b) - (a < b))
conn.execute("CREATE TABLE t(x TEXT)")
for i in range(100):
conn.execute("INSERT INTO t VALUES (?)", (f"item_{i:03d}",))
conn.commit()
cursor = conn.execute("SELECT x FROM t ORDER BY x COLLATE mycoll")
next(cursor)
conn.create_collation("mycoll", lambda a, b: 0) # SQLITE_BUSY → assertionimport sqlite3, _testcapi
conn = sqlite3.connect(":memory:")
_testcapi.set_nomemory(1, 0)
try:
conn.set_trace_callback(lambda s: None)
except (MemoryError, SystemError):
pass
finally:
_testcapi.remove_mem_hooks()