Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Jan 1, 2026

for #6483

cc @ever0de

Summary by CodeRabbit

  • New Features

    • Added autocommit mode for SQLite connections with flexible configuration options
    • Added LEGACY_TRANSACTION_CONTROL constant to maintain backward compatibility
    • New autocommit property on Connection and Cursor objects for runtime transaction control configuration
  • Bug Fixes

    • Improved error handling when operations access closed connections
    • Enhanced connection closing mechanisms for more reliable resource cleanup

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 1, 2026

Warning

Rate limit exceeded

@youknowone has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 59 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 169a3e2 and 8d70096.

📒 Files selected for processing (1)
  • crates/stdlib/src/sqlite.rs
📝 Walkthrough

Walkthrough

Introduces autocommit mode mechanism for sqlite3 connections with three modes (Legacy, Enabled, Disabled), adds public Python-facing autocommit property on Connection and Cursor, exposes LEGACY_TRANSACTION_CONTROL constant, adjusts transaction control flow to respect autocommit state, and improves cleanup safety using sqlite3_close_v2 with early-exit validation for closed connections.

Changes

Cohort / File(s) Changes
Autocommit Mode Infrastructure
crates/stdlib/src/sqlite.rs
Introduces AutocommitMode enum (Legacy, Enabled, Disabled) and TryFromBorrowedObject impl; extends ConnectArgs, Connection, and Cursor to store autocommit state via PyMutex
Public Python API
crates/stdlib/src/sqlite.rs
Exposes LEGACY_TRANSACTION_CONTROL constant and adds autocommit property getters and setters on Connection and Cursor classes
Transaction Control Flow
crates/stdlib/src/sqlite.rs
Modifies execute and executemany paths to conditionally invoke begin_transaction; skips implicit transaction wrapping when autocommit is Enabled
Connection Cleanup & Safety
crates/stdlib/src/sqlite.rs
Adds extern declaration for sqlite3_close_v2; updates Sqlite Drop to use sqlite3_close_v2; adds closed-connection check in Cursor.next with statement cleanup

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client (Python)
    participant Conn as Connection
    participant Cursor as Cursor
    participant SQLite as SQLite DB

    alt Autocommit Disabled (Manual)
        Client->>Conn: execute(sql)
        Conn->>Conn: autocommit check
        Conn->>SQLite: BEGIN
        Conn->>Cursor: create cursor
        Cursor->>SQLite: execute statement
        Client->>Conn: commit()
        Conn->>SQLite: COMMIT
    else Autocommit Enabled
        Client->>Conn: execute(sql)
        Conn->>Conn: autocommit check
        Note over Conn: skip BEGIN
        Conn->>Cursor: create cursor
        Cursor->>SQLite: execute statement
        Note over SQLite: autocommit on DB
    else Autocommit Legacy
        Client->>Conn: execute(sql)
        Conn->>Conn: check LEGACY_TRANSACTION_CONTROL
        Conn->>SQLite: BEGIN
        Conn->>Cursor: create cursor
        Cursor->>SQLite: execute statement
    end

    Conn->>Conn: close()
    Conn->>SQLite: sqlite3_close_v2()
    Note over Conn: handles active statements safely
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

🐰 Three modes hop through the SQLite warren,
Legacy, Enabled, Disabled—each one sparran!
Transactions dance or skip with grace,
Autocommit rules the database space.
Close safely now with sqlite3_close_v2—
munches carrot

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title mentions 'sqlite3 autocommit' which is the main feature added in the changeset, but also includes 'Upgrade dbm' which is not reflected in the provided summary of changes focused on sqlite3.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@youknowone youknowone marked this pull request as ready for review January 1, 2026 01:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4df238 and 169a3e2.

⛔ Files ignored due to path filters (8)
  • Lib/dbm/__init__.py is excluded by !Lib/**
  • Lib/dbm/dumb.py is excluded by !Lib/**
  • Lib/dbm/gnu.py is excluded by !Lib/**
  • Lib/dbm/ndbm.py is excluded by !Lib/**
  • Lib/dbm/sqlite3.py is excluded by !Lib/**
  • Lib/test/test_dbm.py is excluded by !Lib/**
  • Lib/test/test_dbm_dumb.py is excluded by !Lib/**
  • Lib/test/test_dbm_sqlite3.py is excluded by !Lib/**
📒 Files selected for processing (1)
  • crates/stdlib/src/sqlite.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to format Rust code
Always run clippy to lint code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust

Files:

  • crates/stdlib/src/sqlite.rs
🔇 Additional comments (9)
crates/stdlib/src/sqlite.rs (9)

305-338: LGTM!

The AutocommitMode enum and its TryFromBorrowedObject implementation are well-designed. The identity checks (obj.is(&vm.ctx.true_value)) correctly distinguish between True/False and integer values, matching CPython's behavior where autocommit=1 is treated differently from autocommit=True.


360-361: LGTM!

The autocommit field correctly uses the derived Default implementation, which initializes to AutocommitMode::Legacy.


883-883: LGTM!

The autocommit field uses PyMutex<AutocommitMode> for thread-safe access, consistent with other mutable state in the Connection struct.


963-970: LGTM!

The autocommit mode is correctly extracted from ConnectArgs and assigned to the connection during reinitialization.


1778-1791: Consistent with execute() implementation.

The autocommit check mirrors the execute() method. The same verification regarding AutocommitMode::Disabled behavior applies here.


2018-2030: Good safety improvement for cleanup on closed connections.

This early check ensures that when iterating a cursor after the connection is closed, the statement is properly reset to release file locks. The error message is clear and matches CPython's behavior.

Note: There's a theoretical TOCTOU gap between is_closed() and the lock acquisition, but this is acceptable since:

  1. Connection closure is typically single-threaded from Python's perspective
  2. The later db_lock(vm) call would catch any race condition
  3. This is primarily a best-effort cleanup improvement

1569-1579: AI summary inconsistency: Cursor does not have autocommit property.

The AI-generated summary mentions "Added public methods: autocommit (getter) on class Cursor" and "autocommit: PyMutex" in Cursor, but the actual code correctly implements autocommit only at the Connection level. This is the expected behavior since autocommit is a connection-level setting in Python's sqlite3 module.


364-368: LGTM!

The Traverse implementation for ConnectArgs correctly excludes autocommit since AutocommitMode is a simple Copy enum with no Python object references that need GC traversal.


1683-1696: No changes required—the transaction logic correctly implements CPython behavior.

The code correctly handles AutocommitMode::Disabled (corresponding to autocommit=False). Per PEP-249 and CPython sqlite3 specifications, when autocommit=False, implicit transactions via BEGIN are required before DML statements, and the user must explicitly call commit() or rollback(). The term "manual commit mode" refers to requiring explicit commits after the implicit transaction begins, not the absence of implicit transactions.

The condition *zelf.connection.autocommit.lock() != AutocommitMode::Enabled correctly:

  • Calls begin_transaction() for Disabled mode (autocommit=False) → implicit transactions as required ✓
  • Calls begin_transaction() for Legacy mode → respects isolation_level ✓
  • Skips begin_transaction() for Enabled mode (autocommit=True) → true SQLite autocommit ✓

@youknowone youknowone merged commit e58cf84 into RustPython:main Jan 1, 2026
13 checks passed
@youknowone youknowone deleted the dbm branch January 1, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant