Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Nov 30, 2025

#4884

Summary by CodeRabbit

  • Chores
    • Improved debug-only error messages to give clearer guidance when object initialization fails and when subclassing support may be limited.
    • Added a non-functional inline note highlighting a potential safety concern related to the instance type.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 30, 2025

Walkthrough

Adds 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

Cohort / File(s) Summary
Debug error diagnostics
crates/vm/src/types/slot.rs
In Initializer::slot_init, capture the class name when Zelf downcast fails; in debug builds, reprint the error, check for the class name appearing twice, and panic with a message suggesting the type may not support init (prompting to override slot_init) when detected. Adds a non-functional safety comment in __init__.
Enhanced downcast error messages
crates/vm/src/vm/vm_new.rs
In debug assertion path for downcast errors where actual and expected class match, prefix the existing reminder about #[pyclass(with(Constructor))]? with an additional note suggesting the type may not support subclassing well. Only the diagnostic text changed.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Inspect debug-only conditional and panic condition in crates/vm/src/types/slot.rs.
  • Verify the updated diagnostic wording in crates/vm/src/vm/vm_new.rs for clarity and correctness.

Poem

🐰 I nibble logs by lantern light,
Two names echo — what a sight!
A helpful panic, a gentle nudge,
So types behave and errors budge.
Hoppity hop, the fix is bright.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'init debug helper' is concise and clearly describes the main changes: adding debug-only helper logic to the init path for improved error diagnostics.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent 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 080a2f6 and d5af480.

📒 Files selected for processing (2)
  • crates/vm/src/types/slot.rs (1 hunks)
  • crates/vm/src/vm/vm_new.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/vm/src/vm/vm_new.rs
  • crates/vm/src/types/slot.rs
⏰ 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)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Check Rust code with clippy
  • GitHub Check: Run tests under miri
  • GitHub Check: Check the WASM package and demo
  • GitHub Check: Run snippets and cpython tests on wasm-wasi
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Ensure compilation on various targets

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 November 30, 2025 02:09
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: 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 zelf but 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

📥 Commits

Reviewing files that changed from the base of the PR and between b84f7c1 and 080a2f6.

📒 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 running cargo fmt to 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.rs
  • crates/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.

Comment on lines 838 to 859
#[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);
}
};
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 30, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fragile error detection heuristic with potential issues.

The debug diagnostic logic has several concerns:

  1. Line 846: err.as_object().repr(vm)? can fail, which would replace the original error with a repr failure error, masking the actual problem.

  2. 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.

  3. 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.

Copy link
Member Author

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

Copy link
Contributor

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)? with if 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 let block

This makes the debug diagnostic more robust and ensures the original error is always preserved.

@youknowone youknowone merged commit 8e0a86d into RustPython:main Nov 30, 2025
13 checks passed
@youknowone youknowone deleted the init-debug branch November 30, 2025 07:58
@coderabbitai coderabbitai bot mentioned this pull request Dec 16, 2025
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