refactor: inline handle_panic into macro output
This commit is contained in:
parent
be31ca96f7
commit
c93ee00130
|
@ -48,7 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- `__getitem__`, `__setitem__` and `__delitem__` in `#[pymethods]` now implement both a Python mapping and sequence by default. [#2065](https://github.com/PyO3/pyo3/pull/2065)
|
- `__getitem__`, `__setitem__` and `__delitem__` in `#[pymethods]` now implement both a Python mapping and sequence by default. [#2065](https://github.com/PyO3/pyo3/pull/2065)
|
||||||
- Improve performance and error messages for `#[derive(FromPyObject)]` for enums. [#2068](https://github.com/PyO3/pyo3/pull/2068)
|
- Improve performance and error messages for `#[derive(FromPyObject)]` for enums. [#2068](https://github.com/PyO3/pyo3/pull/2068)
|
||||||
- Reduce generated LLVM code size (to improve compile times) for:
|
- Reduce generated LLVM code size (to improve compile times) for:
|
||||||
- internal `handle_panic` helper [#2074](https://github.com/PyO3/pyo3/pull/2074)
|
- internal `handle_panic` helper [#2074](https://github.com/PyO3/pyo3/pull/2074) [#2158](https://github.com/PyO3/pyo3/pull/2158)
|
||||||
- `#[pyfunction]` and `#[pymethods]` argument extraction [#2075](https://github.com/PyO3/pyo3/pull/2075) [#2085](https://github.com/PyO3/pyo3/pull/2085)
|
- `#[pyfunction]` and `#[pymethods]` argument extraction [#2075](https://github.com/PyO3/pyo3/pull/2075) [#2085](https://github.com/PyO3/pyo3/pull/2085)
|
||||||
- `#[pyclass]` type object creation [#2076](https://github.com/PyO3/pyo3/pull/2076) [#2081](https://github.com/PyO3/pyo3/pull/2081) [#2157](https://github.com/PyO3/pyo3/pull/2157)
|
- `#[pyclass]` type object creation [#2076](https://github.com/PyO3/pyo3/pull/2076) [#2081](https://github.com/PyO3/pyo3/pull/2081) [#2157](https://github.com/PyO3/pyo3/pull/2157)
|
||||||
- `__ipow__` now supports modulo argument on Python 3.8+. [#2083](https://github.com/PyO3/pyo3/pull/2083)
|
- `__ipow__` now supports modulo argument on Python 3.8+. [#2083](https://github.com/PyO3/pyo3/pull/2083)
|
||||||
|
|
|
@ -490,10 +490,12 @@ impl<'a> FnSpec<'a> {
|
||||||
{
|
{
|
||||||
use #krate as _pyo3;
|
use #krate as _pyo3;
|
||||||
#deprecations
|
#deprecations
|
||||||
_pyo3::callback::handle_panic(|#py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let #py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#self_conversion
|
#self_conversion
|
||||||
#rust_call
|
#rust_call
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,11 +510,13 @@ impl<'a> FnSpec<'a> {
|
||||||
{
|
{
|
||||||
use #krate as _pyo3;
|
use #krate as _pyo3;
|
||||||
#deprecations
|
#deprecations
|
||||||
_pyo3::callback::handle_panic(|#py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let #py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#self_conversion
|
#self_conversion
|
||||||
#arg_convert
|
#arg_convert
|
||||||
#rust_call
|
#rust_call
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,11 +530,13 @@ impl<'a> FnSpec<'a> {
|
||||||
{
|
{
|
||||||
use #krate as _pyo3;
|
use #krate as _pyo3;
|
||||||
#deprecations
|
#deprecations
|
||||||
_pyo3::callback::handle_panic(|#py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let #py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#self_conversion
|
#self_conversion
|
||||||
#arg_convert
|
#arg_convert
|
||||||
#rust_call
|
#rust_call
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,13 +552,15 @@ impl<'a> FnSpec<'a> {
|
||||||
use #krate as _pyo3;
|
use #krate as _pyo3;
|
||||||
#deprecations
|
#deprecations
|
||||||
use _pyo3::callback::IntoPyCallbackOutput;
|
use _pyo3::callback::IntoPyCallbackOutput;
|
||||||
_pyo3::callback::handle_panic(|#py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let #py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#arg_convert
|
#arg_convert
|
||||||
let result = #rust_call;
|
let result = #rust_call;
|
||||||
let initializer: _pyo3::PyClassInitializer::<#cls> = result.convert(#py)?;
|
let initializer: _pyo3::PyClassInitializer::<#cls> = result.convert(#py)?;
|
||||||
let cell = initializer.create_cell_from_subtype(#py, subtype)?;
|
let cell = initializer.create_cell_from_subtype(#py, subtype)?;
|
||||||
::std::result::Result::Ok(cell as *mut _pyo3::ffi::PyObject)
|
::std::result::Result::Ok(cell as *mut _pyo3::ffi::PyObject)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,7 @@ pub fn pymodule_impl(
|
||||||
/// This autogenerated function is called by the python interpreter when importing
|
/// This autogenerated function is called by the python interpreter when importing
|
||||||
/// the module.
|
/// the module.
|
||||||
pub unsafe extern "C" fn #cb_name() -> *mut #krate::ffi::PyObject {
|
pub unsafe extern "C" fn #cb_name() -> *mut #krate::ffi::PyObject {
|
||||||
use #krate::{self as _pyo3, IntoPyPointer};
|
unsafe { #module_def_name.module_init() }
|
||||||
_pyo3::callback::handle_panic(|_py| ::std::result::Result::Ok(#module_def_name.make_module(_py)?.into_ptr()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -304,7 +304,9 @@ pub fn impl_py_setter_def(cls: &syn::Type, property_type: PropertyType) -> Resul
|
||||||
_value: *mut _pyo3::ffi::PyObject,
|
_value: *mut _pyo3::ffi::PyObject,
|
||||||
_: *mut ::std::os::raw::c_void
|
_: *mut ::std::os::raw::c_void
|
||||||
) -> ::std::os::raw::c_int {
|
) -> ::std::os::raw::c_int {
|
||||||
_pyo3::callback::handle_panic(|_py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let _py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(_py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#slf
|
#slf
|
||||||
let _value = _py
|
let _value = _py
|
||||||
.from_borrowed_ptr_or_opt(_value)
|
.from_borrowed_ptr_or_opt(_value)
|
||||||
|
@ -314,7 +316,7 @@ pub fn impl_py_setter_def(cls: &syn::Type, property_type: PropertyType) -> Resul
|
||||||
let _val = _pyo3::FromPyObject::extract(_value)?;
|
let _val = _pyo3::FromPyObject::extract(_value)?;
|
||||||
|
|
||||||
_pyo3::callback::convert(_py, #setter_impl)
|
_pyo3::callback::convert(_py, #setter_impl)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
__wrap
|
__wrap
|
||||||
}),
|
}),
|
||||||
|
@ -383,10 +385,12 @@ pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType) -> Resul
|
||||||
_slf: *mut _pyo3::ffi::PyObject,
|
_slf: *mut _pyo3::ffi::PyObject,
|
||||||
_: *mut ::std::os::raw::c_void
|
_: *mut ::std::os::raw::c_void
|
||||||
) -> *mut _pyo3::ffi::PyObject {
|
) -> *mut _pyo3::ffi::PyObject {
|
||||||
_pyo3::callback::handle_panic(|_py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let _py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(_py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#slf
|
#slf
|
||||||
_pyo3::callback::convert(_py, #getter_impl)
|
_pyo3::callback::convert(_py, #getter_impl)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
__wrap
|
__wrap
|
||||||
}),
|
}),
|
||||||
|
@ -880,9 +884,11 @@ impl SlotDef {
|
||||||
unsafe extern "C" fn __wrap(_raw_slf: *mut _pyo3::ffi::PyObject, #(#method_arguments),*) -> #ret_ty {
|
unsafe extern "C" fn __wrap(_raw_slf: *mut _pyo3::ffi::PyObject, #(#method_arguments),*) -> #ret_ty {
|
||||||
let _slf = _raw_slf;
|
let _slf = _raw_slf;
|
||||||
#before_call_method
|
#before_call_method
|
||||||
_pyo3::callback::handle_panic(|#py| {
|
let gil = _pyo3::GILPool::new();
|
||||||
|
let #py = gil.python();
|
||||||
|
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
|
||||||
#body
|
#body
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
_pyo3::ffi::PyType_Slot {
|
_pyo3::ffi::PyType_Slot {
|
||||||
slot: _pyo3::ffi::#slot,
|
slot: _pyo3::ffi::#slot,
|
||||||
|
|
|
@ -245,7 +245,11 @@ where
|
||||||
panic_result_into_callback_output(py, panic::catch_unwind(move || -> PyResult<_> { body(py) }))
|
panic_result_into_callback_output(py, panic::catch_unwind(move || -> PyResult<_> { body(py) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_result_into_callback_output<R>(
|
/// Converts the output of std::panic::catch_unwind into a Python function output, either by raising a Python
|
||||||
|
/// exception or by unwrapping the contained success output.
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[inline]
|
||||||
|
pub fn panic_result_into_callback_output<R>(
|
||||||
py: Python,
|
py: Python,
|
||||||
panic_result: Result<PyResult<R>, Box<dyn Any + Send + 'static>>,
|
panic_result: Result<PyResult<R>, Box<dyn Any + Send + 'static>>,
|
||||||
) -> R
|
) -> R
|
||||||
|
|
|
@ -260,14 +260,19 @@ macro_rules! define_pyclass_setattr_slot {
|
||||||
use ::std::option::Option::*;
|
use ::std::option::Option::*;
|
||||||
use $crate::callback::IntoPyCallbackOutput;
|
use $crate::callback::IntoPyCallbackOutput;
|
||||||
use $crate::impl_::pyclass::*;
|
use $crate::impl_::pyclass::*;
|
||||||
$crate::callback::handle_panic(|py| {
|
let gil = $crate::GILPool::new();
|
||||||
let collector = PyClassImplCollector::<$cls>::new();
|
let py = gil.python();
|
||||||
if let Some(value) = ::std::ptr::NonNull::new(value) {
|
$crate::callback::panic_result_into_callback_output(
|
||||||
collector.$set(py, _slf, attr, value).convert(py)
|
py,
|
||||||
} else {
|
::std::panic::catch_unwind(move || -> $crate::PyResult<_> {
|
||||||
collector.$del(py, _slf, attr).convert(py)
|
let collector = PyClassImplCollector::<$cls>::new();
|
||||||
}
|
if let Some(value) = ::std::ptr::NonNull::new(value) {
|
||||||
})
|
collector.$set(py, _slf, attr, value).convert(py)
|
||||||
|
} else {
|
||||||
|
collector.$del(py, _slf, attr).convert(py)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
$crate::ffi::PyType_Slot {
|
$crate::ffi::PyType_Slot {
|
||||||
slot: $crate::ffi::$slot,
|
slot: $crate::ffi::$slot,
|
||||||
|
@ -367,17 +372,22 @@ macro_rules! define_pyclass_binary_operator_slot {
|
||||||
_slf: *mut $crate::ffi::PyObject,
|
_slf: *mut $crate::ffi::PyObject,
|
||||||
_other: *mut $crate::ffi::PyObject,
|
_other: *mut $crate::ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject {
|
) -> *mut $crate::ffi::PyObject {
|
||||||
$crate::callback::handle_panic(|py| {
|
let gil = $crate::GILPool::new();
|
||||||
use $crate::impl_::pyclass::*;
|
let py = gil.python();
|
||||||
let collector = PyClassImplCollector::<$cls>::new();
|
$crate::callback::panic_result_into_callback_output(
|
||||||
let lhs_result = collector.$lhs(py, _slf, _other)?;
|
py,
|
||||||
if lhs_result == $crate::ffi::Py_NotImplemented() {
|
::std::panic::catch_unwind(move || -> $crate::PyResult<_> {
|
||||||
$crate::ffi::Py_DECREF(lhs_result);
|
use $crate::impl_::pyclass::*;
|
||||||
collector.$rhs(py, _other, _slf)
|
let collector = PyClassImplCollector::<$cls>::new();
|
||||||
} else {
|
let lhs_result = collector.$lhs(py, _slf, _other)?;
|
||||||
::std::result::Result::Ok(lhs_result)
|
if lhs_result == $crate::ffi::Py_NotImplemented() {
|
||||||
}
|
$crate::ffi::Py_DECREF(lhs_result);
|
||||||
})
|
collector.$rhs(py, _other, _slf)
|
||||||
|
} else {
|
||||||
|
::std::result::Result::Ok(lhs_result)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
$crate::ffi::PyType_Slot {
|
$crate::ffi::PyType_Slot {
|
||||||
slot: $crate::ffi::$slot,
|
slot: $crate::ffi::$slot,
|
||||||
|
@ -560,17 +570,22 @@ macro_rules! generate_pyclass_pow_slot {
|
||||||
_other: *mut $crate::ffi::PyObject,
|
_other: *mut $crate::ffi::PyObject,
|
||||||
_mod: *mut $crate::ffi::PyObject,
|
_mod: *mut $crate::ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject {
|
) -> *mut $crate::ffi::PyObject {
|
||||||
$crate::callback::handle_panic(|py| {
|
let gil = $crate::GILPool::new();
|
||||||
use $crate::impl_::pyclass::*;
|
let py = gil.python();
|
||||||
let collector = PyClassImplCollector::<$cls>::new();
|
$crate::callback::panic_result_into_callback_output(
|
||||||
let lhs_result = collector.__pow__(py, _slf, _other, _mod)?;
|
py,
|
||||||
if lhs_result == $crate::ffi::Py_NotImplemented() {
|
::std::panic::catch_unwind(move || -> $crate::PyResult<_> {
|
||||||
$crate::ffi::Py_DECREF(lhs_result);
|
use $crate::impl_::pyclass::*;
|
||||||
collector.__rpow__(py, _other, _slf, _mod)
|
let collector = PyClassImplCollector::<$cls>::new();
|
||||||
} else {
|
let lhs_result = collector.__pow__(py, _slf, _other, _mod)?;
|
||||||
::std::result::Result::Ok(lhs_result)
|
if lhs_result == $crate::ffi::Py_NotImplemented() {
|
||||||
}
|
$crate::ffi::Py_DECREF(lhs_result);
|
||||||
})
|
collector.__rpow__(py, _other, _slf, _mod)
|
||||||
|
} else {
|
||||||
|
::std::result::Result::Ok(lhs_result)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
$crate::ffi::PyType_Slot {
|
$crate::ffi::PyType_Slot {
|
||||||
slot: $crate::ffi::Py_nb_power,
|
slot: $crate::ffi::Py_nb_power,
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! Implementation details of `#[pymodule]` which need to be accessible from proc-macro generated code.
|
//! Implementation details of `#[pymodule]` which need to be accessible from proc-macro generated code.
|
||||||
|
|
||||||
use std::{cell::UnsafeCell, panic::AssertUnwindSafe};
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
callback::handle_panic, ffi, types::PyModule, IntoPyPointer, Py, PyObject, PyResult, Python,
|
callback::panic_result_into_callback_output, ffi, types::PyModule, GILPool, IntoPyPointer, Py,
|
||||||
|
PyObject, PyResult, Python,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `Sync` wrapper of `ffi::PyModuleDef`.
|
/// `Sync` wrapper of `ffi::PyModuleDef`.
|
||||||
|
@ -64,8 +65,15 @@ impl ModuleDef {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// The Python GIL must be held.
|
/// The Python GIL must be held.
|
||||||
pub unsafe fn module_init(&'static self) -> *mut ffi::PyObject {
|
pub unsafe fn module_init(&'static self) -> *mut ffi::PyObject {
|
||||||
let unwind_safe_self = AssertUnwindSafe(self);
|
let pool = GILPool::new();
|
||||||
handle_panic(|py| Ok(unwind_safe_self.make_module(py)?.into_ptr()))
|
let py = pool.python();
|
||||||
|
let unwind_safe_self = std::panic::AssertUnwindSafe(self);
|
||||||
|
panic_result_into_callback_output(
|
||||||
|
py,
|
||||||
|
std::panic::catch_unwind(move || -> PyResult<_> {
|
||||||
|
Ok(unwind_safe_self.make_module(py)?.into_ptr())
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'py` due to conflicting requirements
|
error[E0597]: `gil` does not live long enough
|
||||||
--> tests/ui/static_ref.rs:4:1
|
--> tests/ui/static_ref.rs:4:1
|
||||||
|
|
|
|
||||||
4 | #[pyfunction]
|
4 | #[pyfunction]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `gil` dropped here while still borrowed
|
||||||
|
| borrowed value does not live long enough
|
||||||
|
| cast requires that `gil` is borrowed for `'static`
|
||||||
|
|
|
|
||||||
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here...
|
|
||||||
--> tests/ui/static_ref.rs:4:1
|
|
||||||
|
|
|
||||||
4 | #[pyfunction]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
note: ...so that the expression is assignable
|
|
||||||
--> tests/ui/static_ref.rs:4:1
|
|
||||||
|
|
|
||||||
4 | #[pyfunction]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
= note: expected `pyo3::Python<'_>`
|
|
||||||
found `pyo3::Python<'_>`
|
|
||||||
= note: but, the lifetime must be valid for the static lifetime...
|
|
||||||
note: ...so that reference does not outlive borrowed content
|
|
||||||
--> tests/ui/static_ref.rs:4:1
|
|
||||||
|
|
|
||||||
4 | #[pyfunction]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
= note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
Loading…
Reference in New Issue