-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix(sqlite): raise ProgrammingError when operating on a blob with a…
#6286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(sqlite): raise ProgrammingError when operating on a blob with a…
#6286
Conversation
… closed connection, Fixed RustPython#6285
WalkthroughThe PR adds an Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. 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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Lib/test/test_sqlite3/test_dbapi.pyis excluded by!Lib/**
📒 Files selected for processing (1)
crates/stdlib/src/sqlite.rs(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Run tests under miri
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Check Rust code with clippy
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: auto_format
🔇 Additional comments (1)
crates/stdlib/src/sqlite.rs (1)
1010-1012: LGTM! Clean helper method for connection state check.The
is_closed()method correctly checks the connection state by inspecting thedbmutex. This provides a clear, reusable way to determine if the connection has been closed.
| if self.connection.is_closed() { | ||
| return Err(new_programming_error( | ||
| vm, | ||
| "Cannot operate on a closed database".to_owned(), | ||
| )); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify that other blob methods handle closed connections correctly.
The check for closed connections in read() is correct and matches the CPython behavior. However, other blob methods like write, tell, seek, and the subscript operations may also need this check to be consistent.
Run the following script to examine if other blob methods should also include the closed-connection check:
🏁 Script executed:
#!/bin/bash
# Description: Search for all Blob methods to verify consistent closed-connection handling
echo "=== Blob methods in the file ==="
ast-grep --pattern $'impl Blob {
$$$
fn $METHOD($$$) $$$
$$$
}'
echo -e "\n=== Checking which methods call connection.db_lock or check connection state ==="
rg -n -A5 -B2 'impl Blob' crates/stdlib/src/sqlite.rs | rg -A5 'fn (write|tell|seek|__enter__|__exit__|subscript|ass_subscript)'Length of output: 114
The web search doesn't provide targeted information about the specific codebase. Let me generate new shell scripts to examine the Blob implementation directly:
🏁 Script executed:
#!/bin/bash
# Description: Extract Blob impl block and examine all methods
echo "=== Finding impl Blob block ==="
rg -n 'impl Blob' crates/stdlib/src/sqlite.rs -A 300
echo -e "\n=== Counting methods in Blob impl ==="
rg -n 'fn ' crates/stdlib/src/sqlite.rs | grep -A1 -B1 'Blob'Length of output: 12999
🏁 Script executed:
#!/bin/bash
# Search for CPython's blob.c file content from GitHub
echo "=== Searching for CPython blob.c on GitHub ==="
curl -s https://raw.githubusercontent.com/python/cpython/main/Modules/_sqlite/blob.c | head -400Length of output: 9655
Add closed-connection check to other blob methods for consistency with CPython behavior.
CPython's check_blob() function checks connection status on ALL blob operations (read, write, seek, tell, enter, exit). The Rust implementation only added this check to read(). The following methods should include the same check before calling self.inner(vm)?:
write()(line 2207)tell()(line 2222)seek()(line 2227)__enter__()(line 2261)__exit__()(line 2267)subscript()(line 2313)ass_subscript()(line 2350)
Without these checks, operations on other methods could fail with unclear errors when the connection is closed, unlike CPython which provides a consistent error message.
🤖 Prompt for AI Agents
In crates/stdlib/src/sqlite.rs around lines 2176-2360 (affecting the methods
at/near lines 2207, 2222, 2227, 2261, 2267, 2313, 2350), add the same
closed-connection guard used at lines 2176-2181 to each listed blob method:
before calling self.inner(vm)? in write(), tell(), seek(), __enter__(),
__exit__(), subscript(), and ass_subscript(), check if
self.connection.is_closed() and if so return Err(new_programming_error(vm,
"Cannot operate on a closed database".to_owned())); this ensures consistent
CPython-like error messages for all blob operations when the connection is
closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ever0de How do you think about this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@youknowone Can I handle this in a separate issue?
| length: OptionalArg<c_int>, | ||
| vm: &VirtualMachine, | ||
| ) -> PyResult<PyRef<PyBytes>> { | ||
| if self.connection.is_closed() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please put the link in the PR here? it will be easier to access rather than going to git blame -> PR -> links
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please clarify the context? I am currently unable to understand why it's required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not required. Just my personal preference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn’t the official stance of our project, but I’d like to share my personal view on the matter.
If the behavior is something that’s common sense and easily predictable, I don’t think we need to attach a reference. In my opinion, this change falls into that category. Before adding this code, it might have been unclear whether such a check was necessary, but once the code is added, it becomes obvious that it is.
Some behaviors are hard to infer from the code alone. In those cases, having a reference linked is helpful. Depending on the situation, when pointing to the exact code is useful, we link specific line numbers; when it’s more important to refer to the conceptual location, we just mention the function name instead.
youknowone
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| length: OptionalArg<c_int>, | ||
| vm: &VirtualMachine, | ||
| ) -> PyResult<PyRef<PyBytes>> { | ||
| if self.connection.is_closed() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn’t the official stance of our project, but I’d like to share my personal view on the matter.
If the behavior is something that’s common sense and easily predictable, I don’t think we need to attach a reference. In my opinion, this change falls into that category. Before adding this code, it might have been unclear whether such a check was necessary, but once the code is added, it becomes obvious that it is.
Some behaviors are hard to infer from the code alone. In those cases, having a reference linked is helpful. Depending on the situation, when pointing to the exact code is useful, we link specific line numbers; when it’s more important to refer to the conceptual location, we just mention the function name instead.
| if self.connection.is_closed() { | ||
| return Err(new_programming_error( | ||
| vm, | ||
| "Cannot operate on a closed database".to_owned(), | ||
| )); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ever0de How do you think about this comment?
… closed connection,
Fixed #6285
reference:
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.