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

Function exception_group_match

crates/vm/src/exceptions.rs:2756–2819  ·  view source on GitHub ↗

Match exception against except* handler type. Returns (rest, match) tuple.

(
    exc_value: &PyObjectRef,
    match_type: &PyObjectRef,
    vm: &VirtualMachine,
)

Source from the content-addressed store, hash-verified

2754/// Match exception against except* handler type.
2755/// Returns (rest, match) tuple.
2756pub fn exception_group_match(
2757 exc_value: &PyObjectRef,
2758 match_type: &PyObjectRef,
2759 vm: &VirtualMachine,
2760) -> PyResult<(PyObjectRef, PyObjectRef)> {
2761 // Implements _PyEval_ExceptionGroupMatch
2762
2763 // If exc_value is None, return (None, None)
2764 if vm.is_none(exc_value) {
2765 return Ok((vm.ctx.none(), vm.ctx.none()));
2766 }
2767
2768 // Validate match_type and reject ExceptionGroup/BaseExceptionGroup
2769 check_except_star_type_valid(match_type, vm)?;
2770
2771 // Check if exc_value matches match_type
2772 if exc_value.is_instance(match_type, vm)? {
2773 // Full match of exc itself
2774 let is_eg = exc_value.fast_isinstance(vm.ctx.exceptions.base_exception_group);
2775 let matched = if is_eg {
2776 exc_value.clone()
2777 } else {
2778 // Naked exception - wrap it in ExceptionGroup
2779 let excs = vm.ctx.new_tuple(vec![exc_value.clone()]);
2780 let eg_type: PyObjectRef = crate::exception_group::exception_group().to_owned().into();
2781 let wrapped = eg_type.call((vm.ctx.new_str(""), excs), vm)?;
2782 // Copy traceback from original exception
2783 if let Ok(exc) = exc_value.clone().downcast::<types::PyBaseException>()
2784 && let Some(tb) = exc.__traceback__()
2785 && let Ok(wrapped_exc) = wrapped.clone().downcast::<types::PyBaseException>()
2786 {
2787 let _ = wrapped_exc.set___traceback__(tb.into(), vm);
2788 }
2789 wrapped
2790 };
2791 return Ok((vm.ctx.none(), matched));
2792 }
2793
2794 // Check for partial match if it's an exception group
2795 if exc_value.fast_isinstance(vm.ctx.exceptions.base_exception_group) {
2796 let pair = vm.call_method(exc_value, "split", (match_type.clone(),))?;
2797 if !pair.class().is(vm.ctx.types.tuple_type) {
2798 return Err(vm.new_type_error(format!(
2799 "{}.split must return a tuple, not {}",
2800 exc_value.class().name(),
2801 pair.class().name()
2802 )));
2803 }
2804 let pair_tuple: PyTupleRef = pair.try_into_value(vm)?;
2805 if pair_tuple.len() < 2 {
2806 return Err(vm.new_type_error(format!(
2807 "{}.split must return a 2-tuple, got tuple of size {}",
2808 exc_value.class().name(),
2809 pair_tuple.len()
2810 )));
2811 }
2812 let matched = pair_tuple[0].clone();
2813 let rest = pair_tuple[1].clone();

Callers 1

execute_instructionMethod · 0.85

Calls 15

exception_groupFunction · 0.85
noneMethod · 0.80
is_instanceMethod · 0.80
fast_isinstanceMethod · 0.80
__traceback__Method · 0.80
set___traceback__Method · 0.80
isMethod · 0.80
try_into_valueMethod · 0.80
ErrClass · 0.50
is_noneMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected