◐ Shell
clean mode source ↗

Add basic capi error support by bschoenmaeckers · Pull Request #7787 · RustPython/RustPython

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Initializes and exposes C-API exception statics and object/type helpers, adds FFI result conversions and a with_vm helper, makes VM exception APIs public, registers the main interpreter via set_main_interpreter, and wires/tests C-API exception handling and CI test steps.

Changes

C‑API Exception & Object Bridge

Layer / File(s) Summary
Data Shape / Statics
crates/capi/src/pyerrors.rs
Adds define_exception_statics! and many #[unsafe(no_mangle)] pub static mut ...: *mut PyObject; introduces pub(crate) unsafe fn init_exception_statics(zoo: &'static ExceptionZoo).
FFI Result Conversion
crates/capi/src/util.rs
Adds pub(crate) trait FfiResult<Output=Self> with ERR_VALUE and into_output(self, vm); implements conversions for pointers, numerics, bools, floats, usize->isize, and PyResult<T> that set VM exceptions on error.
VM Surface / Visibility
crates/vm/src/vm/mod.rs, crates/vm/src/builtins/type.rs
Promotes VirtualMachine::current_exception and set_exception to pub; adds pub fn take_raised_exception(&self) -> Option<PyBaseExceptionRef>; makes Py<PyType>::is_subtype public.
FFI Function Layer
crates/capi/src/pyerrors.rs, crates/capi/src/pystate.rs
Implements PyErr_* FFI functions (PyErr_Occurred, PyErr_GetRaisedException, PyErr_SetRaisedException, PyErr_SetObject, PyErr_SetString, PyErr_PrintEx, PyErr_DisplayException, PyErr_WriteUnraisable, PyErr_NewException, PyErr_NewExceptionWithDoc, PyErr_GivenExceptionMatches) using with_vm; adds PyEval_RestoreThread stub.
Initialization / Wiring
crates/capi/src/lib.rs, crates/capi/src/pylifecycle.rs, src/lib.rs
Adds pub fn set_main_interpreter(interpreter: Interpreter) that asserts unset, calls unsafe init_exception_statics(&Context::genesis().exceptions), and stores the interpreter; Py_InitializeEx also calls init_exception_statics before creating the interpreter; run() now calls rustpython_capi::set_main_interpreter(interp).
Object helpers / Constants
crates/capi/src/object.rs
Adds pub type PyTypeObject = Py<PyType> and C-ABI functions Py_TYPE, Py_IS_TYPE, PyType_GetFlags, and Py_GetConstantBorrowed.
Tests / Misc / CI / Manifest
crates/capi/src/pyerrors.rs, .cspell.dict/cpython.txt, .github/workflows/ci.yaml, Cargo.toml
Adds unit tests for raised exceptions and type checks; adds pyerrors to cspell; excludes rustpython-capi from workspace tests and adds dedicated CI step to run crates/capi tests; switches workspace pyo3 dependency to the PyO3 git repository.

Sequence Diagram

sequenceDiagram
    participant C as C caller
    participant CApi as rustpython-capi
    participant VM as VirtualMachine
    participant Exc as ExceptionStack

    C->>CApi: PyErr_SetObject(exc_type, value)
    CApi->>VM: with_vm -> &VirtualMachine
    VM->>VM: normalize_exception(type, value) -> PyBaseExceptionRef
    VM-->>CApi: PyBaseExceptionRef
    CApi->>Exc: vm.set_exception(Some(exc))

    C->>CApi: PyErr_Occurred()
    CApi->>VM: with_vm -> vm.current_exception()
    VM-->>CApi: Option<PyBaseExceptionRef>
    CApi-->>C: *mut PyObject or NULL

    C->>CApi: PyErr_GetRaisedException()
    CApi->>VM: with_vm -> vm.take_raised_exception()
    VM-->>CApi: Option<PyBaseExceptionRef>
    CApi-->>C: *mut PyObject or NULL

    C->>CApi: PyErr_PrintEx()
    CApi->>VM: with_vm -> vm.take_raised_exception()
    VM->>VM: print_exception(exc)
    VM-->>CApi: done
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • youknowone

Poem

🐰
I hopped through statics, pointers, and thread,
I bridged PyErrs from C into the VM bed.
With careful paws and tiny leaps,
Exceptions wake from borrowed sleeps.
A carrot for tests — may reviews be sped.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add basic capi error support' accurately describes the primary changes, which comprehensively add C-API error handling infrastructure including exception statics, FFI functions, and utilities.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.