-
Notifications
You must be signed in to change notification settings - Fork 1.4k
init debug helper
#6315
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
init debug helper
#6315
Conversation
WalkthroughAdds debug-only diagnostics to downcast/init error paths in two VM modules: captures class names, inspects error messages for duplicate class occurrences, and augments/panics with a suggestion about types that may not support init or subclassing. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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). (11)
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
🧹 Nitpick comments (1)
crates/vm/src/types/slot.rs (1)
866-866: TODO comment lacks specificity.The comment mentions a potential safety concern about
zelfbut doesn't explain what the concern is or under what conditions it might be unsafe. This makes it difficult to evaluate or address the issue.Please clarify the safety concern with more details. For example:
// TODO: check if this is safe. When __init__ is called on an uninitialized or // incorrectly typed object, zelf might not have the expected payload type. // Consider whether zelf should be `PyObjectRef` with explicit type checking.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
crates/vm/src/types/slot.rs(1 hunks)crates/vm/src/vm/vm_new.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Follow the default rustfmt code style by runningcargo fmtto format Rust code
Always run clippy to lint Rust 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/vm/src/types/slot.rscrates/vm/src/vm/vm_new.rs
🧬 Code graph analysis (1)
crates/vm/src/types/slot.rs (2)
crates/vm/src/stdlib/ctypes/field.rs (2)
zelf(96-97)zelf(196-197)crates/derive-impl/src/error.rs (1)
panic(106-112)
⏰ 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). (1)
- GitHub Check: Run snippets and cpython tests (windows-latest)
🔇 Additional comments (1)
crates/vm/src/vm/vm_new.rs (1)
512-512: LGTM! Helpful debug diagnostic message.The extended error message provides useful guidance for developers encountering downcast failures when class IDs match, pointing them toward the
#[pyclass(with(Constructor))]attribute as a potential solution.
| #[cfg(debug_assertions)] | ||
| let class_name_for_debug = zelf.class().name().to_string(); | ||
|
|
||
| let zelf = match zelf.try_into_value(vm) { | ||
| Ok(zelf) => zelf, | ||
| Err(err) => { | ||
| #[cfg(debug_assertions)] | ||
| { | ||
| let msg = err.as_object().repr(vm)?; | ||
| let double_appearance = | ||
| msg.as_str().matches(&class_name_for_debug as &str).count() == 2; | ||
| if double_appearance { | ||
| panic!( | ||
| "This type `{}` doesn't seem to support `init`. Override `slot_init` instead: {}", | ||
| class_name_for_debug, msg | ||
| ); | ||
| } | ||
| } | ||
| return Err(err); | ||
| } | ||
| }; |
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.
Fragile error detection heuristic with potential issues.
The debug diagnostic logic has several concerns:
-
Line 846:
err.as_object().repr(vm)?can fail, which would replace the original error with a repr failure error, masking the actual problem. -
Line 848: Counting class name occurrences in the error message is fragile and depends on exact error message formatting. This heuristic could produce false positives or miss legitimate cases if error message formats change.
-
Lines 850-853: Using
panic!in error handling is unconventional. In debug builds, this immediately crashes rather than allowing normal error propagation, which could complicate debugging in some scenarios.
Consider these alternatives:
- Use a more robust detection method (e.g., error type checking rather than message parsing)
- Log a warning instead of panicking to preserve normal error flow
- Handle the
repr()failure gracefully to avoid masking the original error
Apply this diff to handle repr() failure safely:
#[cfg(debug_assertions)]
{
- let msg = err.as_object().repr(vm)?;
+ if let Ok(msg) = err.as_object().repr(vm) {
- let double_appearance =
- msg.as_str().matches(&class_name_for_debug as &str).count() == 2;
- if double_appearance {
- panic!(
- "This type `{}` doesn't seem to support `init`. Override `slot_init` instead: {}",
- class_name_for_debug, msg
- );
+ let double_appearance =
+ msg.as_str().matches(&class_name_for_debug as &str).count() == 2;
+ if double_appearance {
+ panic!(
+ "This type `{}` doesn't seem to support `init`. Override `slot_init` instead: {}",
+ class_name_for_debug, msg
+ );
+ }
}
}🤖 Prompt for AI Agents
crates/vm/src/types/slot.rs around lines 838 to 858: the debug diagnostic
currently calls err.as_object().repr(vm)? (which can fail and mask the original
error), uses fragile string-occurrence heuristics to detect the class-name, and
panics on detection; change this to first try to inspect the error in a
non-fallible way (prefer checking the error type via downcast/pattern-match or a
stable error variant rather than parsing repr), if you must render repr() call
wrap it in a safe fallible path (e.g., match or map_err) so a repr failure is
ignored/logged and the original err is preserved, replace panic! with a
non-aborting diagnostic (log::warn! or vm logger) that includes any
safely-obtained context, and always return Err(err) so normal error propagation
is preserved.
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.
@coderabbitai please apply it for me
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, I'll provide the complete fixed version of the slot_init function. Here's the updated code with the safer error handling:
#[pyslot]
#[inline]
fn slot_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
#[cfg(debug_assertions)]
let class_name_for_debug = zelf.class().name().to_string();
let zelf = match zelf.try_into_value(vm) {
Ok(zelf) => zelf,
Err(err) => {
#[cfg(debug_assertions)]
{
if let Ok(msg) = err.as_object().repr(vm) {
let double_appearance =
msg.as_str().matches(&class_name_for_debug as &str).count() == 2;
if double_appearance {
panic!(
"This type `{}` doesn't seem to support `init`. Override `slot_init` instead: {}",
class_name_for_debug, msg
);
}
}
}
return Err(err);
}
};
let args: Self::Args = args.bind(vm)?;
Self::init(zelf, args, vm)
}What changed:
- Wrapped
err.as_object().repr(vm)?withif let Ok(msg) = err.as_object().repr(vm) - This prevents the repr() call from failing and masking the original error
- If repr() fails, the diagnostic is simply skipped and the original error is returned
- The indentation of the subsequent lines is adjusted to be inside the
if letblock
This makes the debug diagnostic more robust and ensures the original error is always preserved.
080a2f6 to
d5af480
Compare
#4884
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.