# err_state.rs - source
Source of the Rust file `/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-0.13.2/src/err/err_state.rs`.
Keywords: rust, rustlang, rust-lang

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69

    use crate::{
        exceptions::PyBaseException, ffi, types::PyType, IntoPy, IntoPyPointer, Py, PyObject, Python,
    };

    #[derive(Clone)]
    pub(crate) struct PyErrStateNormalized {
        pub ptype: Py<PyType>,
        pub pvalue: Py<PyBaseException>,
        pub ptraceback: Option<PyObject>,
    }

    pub(crate) enum PyErrState {
        Lazy {
            ptype: Py<PyType>,
            pvalue: Box<dyn FnOnce(Python) -> PyObject + Send + Sync>,
        },
        FfiTuple {
            ptype: Option<PyObject>,
            pvalue: Option<PyObject>,
            ptraceback: Option<PyObject>,
        },
        Normalized(PyErrStateNormalized),
    }

    /// Helper conversion trait that allows to use custom arguments for lazy exception construction.
    pub trait PyErrArguments: Send + Sync {
        /// Arguments for exception
        fn arguments(self, py: Python) -> PyObject;
    }

    impl<T> PyErrArguments for T
    where
        T: IntoPy<PyObject> + Send + Sync,
    {
        fn arguments(self, py: Python) -> PyObject {
            self.into_py(py)
        }
    }

    pub(crate) fn boxed_args(
        args: impl PyErrArguments + 'static,
    ) -> Box<dyn FnOnce(Python) -> PyObject + Send + Sync> {
        Box::new(|py| args.arguments(py))
    }

    impl PyErrState {
        pub(crate) fn into_ffi_tuple(
            self,
            py: Python,
        ) -> (*mut ffi::PyObject, *mut ffi::PyObject, *mut ffi::PyObject) {
            match self {
                PyErrState::Lazy { ptype, pvalue } => (
                    ptype.into_ptr(),
                    pvalue(py).into_ptr(),
                    std::ptr::null_mut(),
                ),
                PyErrState::FfiTuple {
                    ptype,
                    pvalue,
                    ptraceback,
                } => (ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr()),
                PyErrState::Normalized(PyErrStateNormalized {
                    ptype,
                    pvalue,
                    ptraceback,
                }) => (ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr()),
            }
        }
    }