From f854c38f3632e035f23f4b2939dca9cfdab09308 Mon Sep 17 00:00:00 2001 From: Yujong Lee Date: Sun, 6 Sep 2026 16:25:37 -0700 Subject: [PATCH] await test --- .../tests/callback_lifecycle.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/litellm-rust/crates/python-interop/tests/callback_lifecycle.rs b/litellm-rust/crates/python-interop/tests/callback_lifecycle.rs index 69f0705515f..ed60f8a22a8 100644 --- a/litellm-rust/crates/python-interop/tests/callback_lifecycle.rs +++ b/litellm-rust/crates/python-interop/tests/callback_lifecycle.rs @@ -151,3 +151,38 @@ fn outcome_identifies_binding(scenario_scope: Py, #[case] awaited: bool) Ok(()) }) } + +#[rstest] +fn awaited_raise_surfaces_when_driven(scenario_scope: Py) -> PyResult<()> { + use litellm_python_interop::{InvocationMode, InvocationOutcome, PreparedCall}; + use pyo3::types::PyTuple; + Python::attach(|py| { + let globals = scenario_scope.bind(py); + py.run( + c"events = []\nerror = ValueError('await failure')\nasync def callback():\n events.append('started')\n raise error\ndef drive(coroutine):\n try:\n coroutine.send(None)\n return False\n except BaseException as caught:\n return caught is error\n", + Some(globals), + None, + )?; + let started = || -> PyResult { Ok(globals.get_item("events")?.unwrap().len()?) }; + let call = PreparedCall::new( + InvocationMode::Await, + globals.get_item("callback")?.unwrap().unbind(), + PyTuple::empty(py).unbind(), + None, + ); + let pending = match call.invoke(py)? { + InvocationOutcome::Awaitable(value) => value, + InvocationOutcome::Returned(_) => panic!("await binding produced a settled outcome"), + }; + assert_eq!(started()?, 0); + assert!( + globals + .get_item("drive")? + .unwrap() + .call1((pending,))? + .extract::()? + ); + assert_eq!(started()?, 1); + Ok(()) + }) +}