1- use pyo3:: types:: { PyModule , PyTuple } ;
1+ use pyo3:: types:: { PyModule , PyTuple , PyTracebackMethods } ;
22use pyo3:: { append_to_inittab, conversion:: ToPyObject , prelude:: * , Py , PyAny , PyResult , Python } ;
33
44mod py_module;
@@ -15,12 +15,43 @@ fn convert_arg(py: Python, arg: Arg) -> PyObject {
1515 }
1616}
1717
18+ fn wrap_gil < T , F : FnOnce ( Python ) -> PyResult < T > > ( err : T , f : F ) -> T {
19+ let result = Python :: with_gil ( |py| {
20+ f ( py) . map_err ( |err| {
21+ let tb = err. traceback_bound ( py) . and_then ( |x|{
22+ if let Ok ( x) = x. format ( ) {
23+ Some ( x)
24+ } else {
25+ None
26+ }
27+ } ) ;
28+ let mut s = err. into_value ( py) . to_string ( ) ;
29+ if let Some ( tb) = tb {
30+ s += "\n " ;
31+ s += & tb;
32+ }
33+ s
34+ } )
35+ } ) ;
36+ match result {
37+ Ok ( x) => x,
38+ Err ( error) => {
39+ let mem = extism_pdk:: Memory :: from_bytes ( & error)
40+ . expect ( "Load Python error message into Extism memory" ) ;
41+ unsafe {
42+ extism_pdk:: extism:: error_set ( mem. offset ( ) ) ;
43+ }
44+ err
45+ }
46+ }
47+ }
48+
1849#[ no_mangle]
1950pub extern "C" fn __invoke ( index : u32 , shared : bool ) {
20- Python :: with_gil ( |py| -> PyResult < ( ) > {
51+ wrap_gil ( ( ) , |py| {
2152 let call_args = unsafe { CALL_ARGS . pop ( ) } ;
2253 let mut args: Vec < PyObject > = call_args
23- . unwrap ( )
54+ . unwrap ( )
2455 . into_iter ( )
2556 . map ( |x| convert_arg ( py, x) )
2657 . collect ( ) ;
@@ -31,13 +62,12 @@ pub extern "C" fn __invoke(index: u32, shared: bool) {
3162 let fun: Py < PyAny > = m. getattr ( "__invoke" ) ?. into ( ) ;
3263 fun. call1 ( py, args) ?;
3364 Ok ( ( ) )
34- } )
35- . unwrap ( )
65+ } ) ;
3666}
3767
3868#[ no_mangle]
3969pub extern "C" fn __invoke_i32 ( index : u32 , shared : bool ) -> i32 {
40- Python :: with_gil ( |py| -> PyResult < i32 > {
70+ wrap_gil ( - 1 , |py| -> PyResult < i32 > {
4171 let call_args = unsafe { CALL_ARGS . pop ( ) } ;
4272 let mut args: Vec < PyObject > = call_args
4373 . unwrap ( )
@@ -55,12 +85,11 @@ pub extern "C" fn __invoke_i32(index: u32, shared: bool) -> i32 {
5585 }
5686 Ok ( 0 )
5787 } )
58- . unwrap ( )
5988}
6089
6190#[ no_mangle]
6291pub extern "C" fn __invoke_i64 ( index : u32 , shared : bool ) -> i64 {
63- Python :: with_gil ( |py| -> PyResult < i64 > {
92+ wrap_gil ( - 1 , |py| -> PyResult < i64 > {
6493 let call_args = unsafe { CALL_ARGS . pop ( ) } ;
6594 let mut args: Vec < PyObject > = call_args
6695 . unwrap ( )
@@ -77,8 +106,7 @@ pub extern "C" fn __invoke_i64(index: u32, shared: bool) -> i64 {
77106 return Ok ( res) ;
78107 }
79108 Ok ( 0 )
80- } )
81- . unwrap ( )
109+ } ) . into ( )
82110}
83111
84112enum Arg {
0 commit comments