◐ Shell
clean mode source ↗

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:

  1. The drop_db() method takes ownership via .take(), ensuring clean Drop trait execution
  2. Statement finalization happens through RAII when SqliteStatement is dropped
  3. The existing test suite (including the new tests I created) confirms proper cleanup behavior
  4. 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.