Bump libsqlite3-sys from 0.28 to 0.36 by ever0de · Pull Request #6472 · RustPython/RustPython
I created comprehensive tests comparing CPython's behavior with RustPython when closing connections with active cursors. Both implementations behave identically - they successfully close the connection even when cursors remain active, and subsequent cursor operations properly raise ProgrammingError.
Investigation of sqlite3_close vs sqlite3_close_v2:
While CPython does use sqlite3_close_v2() for its deferred cleanup semantics, libsqlite3-sys intentionally removed sqlite3_close_v2 from its API in version 0.29.0 (rusqlite/rusqlite@4390720).
The commit message explicitly states:
Omit API
sqlite3_close_v2 (for gced languages)
The rationale is that sqlite3_close_v2 is specifically designed for garbage-collected languages where destructor order is non-deterministic. In Rust, with its deterministic RAII-based resource management, the v2 variant is unnecessary. The library maintainers deliberately chose to expose only sqlite3_close as the canonical close function for Rust applications.
This means the use of sqlite3_close() in this PR is not only necessary due to API constraints but also aligns with rusqlite's design philosophy.
Why it works safely:
Our implementation is safe because:
- The
drop_db()method takes ownership via.take(), ensuring clean Drop trait execution - Statement finalization happens through RAII when
SqliteStatementis dropped - The existing test suite (including the new tests I created) confirms proper cleanup behavior
- Rust's ownership system guarantees deterministic cleanup order, unlike garbage-collected languages
The current implementation matches CPython's observable behavior even though the internal mechanism differs due to library design decisions.