MCPcopy Index your code
hub / github.com/RustPython/RustPython / prep_reraise_star

Function prep_reraise_star

crates/vm/src/exceptions.rs:2823–2888  ·  view source on GitHub ↗

Prepare exception for reraise in except* block. Implements _PyExc_PrepReraiseStar

(orig: PyObjectRef, excs: PyObjectRef, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

2821/// Prepare exception for reraise in except* block.
2822/// Implements _PyExc_PrepReraiseStar
2823pub fn prep_reraise_star(orig: PyObjectRef, excs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
2824 use crate::builtins::PyList;
2825
2826 let excs_list = excs
2827 .downcast::<PyList>()
2828 .map_err(|_| vm.new_type_error("expected list for prep_reraise_star"))?;
2829
2830 let excs_vec: Vec<PyObjectRef> = excs_list.borrow_vec().to_vec();
2831
2832 // If no exceptions to process, return None
2833 if excs_vec.is_empty() {
2834 return Ok(vm.ctx.none());
2835 }
2836
2837 // Special case: naked exception (not an ExceptionGroup)
2838 // Only one except* clause could have executed, so there's at most one exception to raise
2839 if !orig.fast_isinstance(vm.ctx.exceptions.base_exception_group) {
2840 // Find first non-None exception
2841 let first = excs_vec.into_iter().find(|e| !vm.is_none(e));
2842 return Ok(first.unwrap_or_else(|| vm.ctx.none()));
2843 }
2844
2845 // Split excs into raised (new) and reraised (from original) by comparing metadata
2846 let mut raised: Vec<PyObjectRef> = Vec::new();
2847 let mut reraised: Vec<PyObjectRef> = Vec::new();
2848
2849 for exc in excs_vec {
2850 if vm.is_none(&exc) {
2851 continue;
2852 }
2853 // Check if this exception came from the original group
2854 if is_exception_from_orig(&exc, &orig, vm) {
2855 reraised.push(exc);
2856 } else {
2857 raised.push(exc);
2858 }
2859 }
2860
2861 // If no exceptions to reraise, return None
2862 if raised.is_empty() && reraised.is_empty() {
2863 return Ok(vm.ctx.none());
2864 }
2865
2866 // Project reraised exceptions onto original structure to preserve nesting
2867 let reraised_eg = exception_group_projection(&orig, &reraised, vm)?;
2868
2869 // If no new raised exceptions, just return the reraised projection
2870 if raised.is_empty() {
2871 return Ok(reraised_eg);
2872 }
2873
2874 // Combine raised with reraised_eg
2875 if !vm.is_none(&reraised_eg) {
2876 raised.push(reraised_eg);
2877 }
2878
2879 // If only one exception, return it directly
2880 if raised.len() == 1 {

Callers 1

call_intrinsic_2Method · 0.85

Calls 15

newFunction · 0.85
is_exception_from_origFunction · 0.85
exception_groupFunction · 0.85
to_vecMethod · 0.80
borrow_vecMethod · 0.80
noneMethod · 0.80
fast_isinstanceMethod · 0.80
is_emptyMethod · 0.45
findMethod · 0.45
into_iterMethod · 0.45
is_noneMethod · 0.45

Tested by

no test coverage detected