pub fn run_and_handle_error(&mut self) -> PythonRunResult {
        // There are underdefined lifetime bugs at play here. There is no
        // explicit lifetime for the PyObject's returned. If we don't have
        // the local variable in scope, we can get into a situation where
        // drop() on self is called before the PyObject's drop(). This is
        // problematic because PyObject's drop() attempts to acquire the GIL.
        // If the interpreter is shut down, there is no GIL to acquire, and
        // we may segfault.
        // TODO look into setting lifetimes properly so the compiler can
        // prevent some issues.
        let res = self.run();
        let py = self.acquire_gil();

        match res {
            Ok(_) => PythonRunResult::Ok {},
            Err(err) => {
                // SystemExit is special in that PyErr_PrintEx() will call
                // exit() if it is seen. So, we handle it manually so we can
                // return an exit code instead of exiting.

                // TODO surely the cpython crate offers a better way to do this...
                err.restore(py);
                let matches =
                    unsafe { pyffi::PyErr_ExceptionMatches(pyffi::PyExc_SystemExit) } != 0;
                let err = cpython::PyErr::fetch(py);

                if matches {
                    return PythonRunResult::Exit {
                        code: match self.handle_system_exit(py, err) {
                            Ok(code) => code,
                            Err(msg) => {
                                eprintln!("{}", msg);
                                1
                            }
                        },
                    };
                }

                self.print_err(err);

                PythonRunResult::Err {}
            }
        }
    }
/// Runs the interpreter and handles any exception that was raised.
Runs the interpreter and handles any exception that was raised.
Runs the interpreter and handles any exception that was raised .
pub fn run_and_handle_error(&mut self) -> PythonRunResult {
        // There are underdefined lifetime bugs at play here. There is no
        // explicit lifetime for the PyObject's returned. If we don't have
        // the local variable in scope, we can get into a situation where
        // drop() on self is called before the PyObject's drop(). This is
        // problematic because PyObject's drop() attempts to acquire the GIL.
        // If the interpreter is shut down, there is no GIL to acquire, and
        // we may segfault.
        // TODO look into setting lifetimes properly so the compiler can
        // prevent some issues.
        let res = self.run();
        let py = self.acquire_gil();
        match res {
            Ok(_) => PythonRunResult::Ok {},
            Err(err) => {
                // SystemExit is special in that PyErr_PrintEx() will call
                // exit() if it is seen. So, we handle it manually so we can
                // return an exit code instead of exiting.
                // TODO surely the cpython crate offers a better way to do this...
                err.restore(py);
                let matches =
                    unsafe { pyffi::PyErr_ExceptionMatches(pyffi::PyExc_SystemExit) } != 0;
                let err = cpython::PyErr::fetch(py);
                if matches {
                    return PythonRunResult::Exit {
                        code: match self.handle_system_exit(py, err) {
                            Ok(code) => code,
                            Err(msg) => {
                                eprintln!("{}", msg);
                                1
                            }
                        },
                    };
                }
                self.print_err(err);
                PythonRunResult::Err {}
            }
        }
    }
pub fn run_and_handle_error ( & mut self ) -> PythonRunResult { // There are underdefined lifetime bugs at play here. There is no // explicit lifetime for the PyObject's returned. If we don't have // the local variable in scope, we can get into a situation where // drop() on self is called before the PyObject's drop(). This is // problematic because PyObject's drop() attempts to acquire the GIL. // If the interpreter is shut down, there is no GIL to acquire, and // we may segfault. // TODO look into setting lifetimes properly so the compiler can // prevent some issues. let res = self . run ( ) ; let py = self . acquire_gil ( ) ; match res { Ok ( _ ) => PythonRunResult :: Ok { } , Err ( err ) => { // SystemExit is special in that PyErr_PrintEx() will call // exit() if it is seen. So, we handle it manually so we can // return an exit code instead of exiting. // TODO surely the cpython crate offers a better way to do this... err . restore ( py ) ; let matches = unsafe { pyffi :: PyErr_ExceptionMatches ( pyffi :: PyExc_SystemExit ) } != 0 ; let err = cpython :: PyErr :: fetch ( py ) ; if matches { return PythonRunResult :: Exit { code : match self . handle_system_exit ( py , err ) { Ok ( code ) => code , Err ( msg ) => { eprintln ! ( " " msg ) ; 1 } } , } ; } self . print_err ( err ) ; PythonRunResult :: Err { } } } }
Runs the interpreter and handles any exception that was raised.
Runs the interpreter and handles any exception that was raised .
&mut self