From 9a2d9083422965c9be51ea248ae1841753e72eb2 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Sat, 7 Mar 2020 09:59:49 +0000 Subject: [PATCH] Simplify callback code using callback_body! macro --- pyo3-derive-backend/src/module.rs | 7 +- pyo3-derive-backend/src/pymethod.rs | 87 +++++++----------------- src/callback.rs | 69 ++++++++++++++++--- src/class/basic.rs | 19 ++---- src/class/buffer.rs | 17 ++--- src/class/macros.rs | 101 +++++++++------------------- src/class/sequence.rs | 29 +++----- src/lib.rs | 1 - tests/ui/static_ref.stderr | 12 ++-- 9 files changed, 142 insertions(+), 200 deletions(-) diff --git a/pyo3-derive-backend/src/module.rs b/pyo3-derive-backend/src/module.rs index 9cd37bd7..54abda71 100644 --- a/pyo3-derive-backend/src/module.rs +++ b/pyo3-derive-backend/src/module.rs @@ -219,16 +219,11 @@ fn function_c_wrapper(name: &Ident, spec: &method::FnSpec<'_>) -> TokenStream { _kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject { const _LOCATION: &'static str = concat!(stringify!(#name), "()"); - - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body!(_py, { let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); #body - - pyo3::callback::convert(_py, _result) }) } } diff --git a/pyo3-derive-backend/src/pymethod.rs b/pyo3-derive-backend/src/pymethod.rs index 3d19983e..64bf7b9a 100644 --- a/pyo3-derive-backend/src/pymethod.rs +++ b/pyo3-derive-backend/src/pymethod.rs @@ -105,9 +105,7 @@ fn impl_wrap_common( { const _LOCATION: &'static str = concat!( stringify!(#cls), ".", stringify!(#python_name), "()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { #slf pyo3::callback::convert(_py, #body) }) @@ -124,16 +122,12 @@ fn impl_wrap_common( { const _LOCATION: &'static str = concat!( stringify!(#cls), ".", stringify!(#python_name), "()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { #slf let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); - #body - - pyo3::callback::convert(_py, _result) + pyo3::callback::convert(_py, #body) }) } } @@ -155,17 +149,13 @@ pub fn impl_proto_wrap(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { _kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject { const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _slf = _py.from_borrowed_ptr::>(_slf); #borrow_self let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); - #body - - pyo3::callback::convert(_py, _result) + pyo3::callback::convert(_py, #body) }) } } @@ -177,11 +167,7 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { let python_name = &spec.python_name; let names: Vec = get_arg_names(&spec); let cb = quote! { #cls::#name(#(#names),*) }; - let body = impl_arg_params_( - spec, - cb, - quote! { pyo3::derive_utils::IntoPyNewResult::into_pynew_result }, - ); + let body = impl_arg_params(spec, cb); quote! { #[allow(unused_mut)] @@ -193,14 +179,11 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { use pyo3::type_object::PyTypeInfo; const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); - #body - + let _result = pyo3::derive_utils::IntoPyNewResult::into_pynew_result(#body); let cell = pyo3::PyClassInitializer::from(_result?).create_cell(_py)?; Ok(cell as *mut pyo3::ffi::PyObject) }) @@ -225,16 +208,12 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { _kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject { const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _cls = pyo3::types::PyType::from_type_ptr(_py, _cls as *mut pyo3::ffi::PyTypeObject); let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); - #body - - pyo3::callback::convert(_py, _result) + pyo3::callback::convert(_py, #body) }) } } @@ -257,15 +236,11 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { _kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject { const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); - #body - - pyo3::callback::convert(_py, _result) + pyo3::callback::convert(_py, #body) }) } } @@ -314,10 +289,7 @@ pub(crate) fn impl_wrap_getter( _slf: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> *mut pyo3::ffi::PyObject { const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _slf = _py.from_borrowed_ptr::>(_slf); #borrow_self pyo3::callback::convert(_py, #getter_impl) @@ -343,9 +315,9 @@ fn impl_call_setter(spec: &FnSpec) -> syn::Result { let name = &spec.name; let fncall = if py_arg.is_some() { - quote!(pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name(_py, _val))?;) + quote!(pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name(_py, _val))?) } else { - quote!(pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name(_val))?;) + quote!(pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name(_val))?) }; Ok(fncall) @@ -359,7 +331,7 @@ pub(crate) fn impl_wrap_setter( let (python_name, setter_impl) = match property_type { PropertyType::Descriptor(field) => { let name = field.ident.as_ref().unwrap(); - (name.unraw(), quote!(_slf.#name = _val;)) + (name.unraw(), quote!({ _slf.#name = _val; })) } PropertyType::Function(spec) => (spec.python_name.clone(), impl_call_setter(&spec)?), }; @@ -372,14 +344,13 @@ pub(crate) fn impl_wrap_setter( _value: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> pyo3::libc::c_int { const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); - let _pool = pyo3::GILPool::new(); - let _py = _pool.python(); - pyo3::run_callback(_py, || { + pyo3::callback_body_without_convert!(_py, { let _slf = _py.from_borrowed_ptr::>(_slf); #borrow_self let _value = _py.from_borrowed_ptr::(_value); let _val = pyo3::FromPyObject::extract(_value)?; - pyo3::callback::convert(_py, {#setter_impl}) + + pyo3::callback::convert(_py, #setter_impl) }) } }) @@ -398,12 +369,10 @@ fn impl_call(_cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { quote! { _slf.#fname(#(#names),*) } } -fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStream) -> TokenStream { +pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream { if spec.args.is_empty() { return quote! { - let _result = { - #into_result (#body) - }; + #body }; } @@ -444,7 +413,7 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre } let num_normal_params = params.len(); // create array of arguments, and then parse - quote! { + quote! {{ use pyo3::ObjectProtocol; const PARAMS: &'static [pyo3::derive_utils::ParamDescription] = &[ #(#params),* @@ -466,16 +435,8 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre #(#param_conversion)* - let _result = #into_result(#body); - } -} - -pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream { - impl_arg_params_( - spec, - body, - quote! { pyo3::derive_utils::IntoPyResult::into_py_result }, - ) + #body + }} } /// Re option_pos: The option slice doesn't contain the py: Python argument, so the argument diff --git a/src/callback.rs b/src/callback.rs index 68603d30..4b0b512a 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -152,14 +152,65 @@ where T::ERR_VALUE } +/// Use this macro for all internal callback functions which Python will call. +/// +/// It sets up the GILPool and converts the output into a Python object. It also restores +/// any python error returned as an Err variant from the body. +/// +/// # Safety +/// This macro assumes the GIL is held. (It makes use of unsafe code, so usage of it is only +/// possible inside unsafe blocks.) #[doc(hidden)] -pub fn run_callback(py: Python, callback: F) -> T -where - F: FnOnce() -> PyResult, - T: PyCallbackOutput, -{ - callback().unwrap_or_else(|e| { - e.restore(py); - T::ERR_VALUE - }) +#[macro_export] +macro_rules! callback_body { + ($py:ident, $body:expr) => {{ + $crate::callback_body_without_convert!($py, $crate::callback::convert($py, $body)) + }}; +} + +/// Variant of the above which does not perform the callback conversion. This allows the callback +/// conversion to be done manually in the case where lifetimes might otherwise cause issue. +/// +/// For example this pyfunction: +/// +/// ```ignore +/// fn foo(&self) -> &Bar { +/// &self.bar +/// } +/// ``` +/// +/// It is wrapped in proc macros with callback_body_without_convert like so: +/// +/// ```ignore +/// pyo3::callback_body_without_convert!(py, { +/// let _slf = #slf; +/// pyo3::callback::convert(py, #foo) +/// }) +/// ``` +/// +/// If callback_body was used instead: +/// +/// ```ignore +/// pyo3::callback_body!(py, { +/// let _slf = #slf; +/// #foo +/// }) +/// ``` +/// +/// Then this will fail to compile, because the result of #foo borrows _slf, but _slf drops when +/// the block passed to the macro ends. +#[doc(hidden)] +#[macro_export] +macro_rules! callback_body_without_convert { + ($py:ident, $body:expr) => {{ + let pool = $crate::GILPool::new(); + + let $py = pool.python(); + let callback = move || -> $crate::PyResult<_> { $body }; + + callback().unwrap_or_else(|e| { + e.restore(pool.python()); + $crate::callback::callback_error() + }) + }}; } diff --git a/src/class/basic.rs b/src/class/basic.rs index 74057bb5..d9996e6e 100644 --- a/src/class/basic.rs +++ b/src/class/basic.rs @@ -11,8 +11,8 @@ use crate::callback::HashCallbackOutput; use crate::class::methods::PyMethodDef; use crate::{ - callback, exceptions, ffi, run_callback, FromPyObject, GILPool, IntoPy, ObjectProtocol, PyAny, - PyCell, PyClass, PyErr, PyObject, PyResult, + exceptions, ffi, FromPyObject, IntoPy, ObjectProtocol, PyAny, PyCell, PyClass, PyErr, PyObject, + PyResult, }; use std::os::raw::c_int; @@ -218,9 +218,7 @@ where where T: for<'p> PyObjectGetAttrProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { // Behave like python's __getattr__ (as opposed to __getattribute__) and check // for existing fields and methods first let existing = ffi::PyObject_GenericGetAttr(slf, arg); @@ -233,7 +231,7 @@ where let slf = py.from_borrowed_ptr::>(slf); let arg = py.from_borrowed_ptr::(arg); - callback::convert(py, call_ref!(slf, __getattr__, arg)) + call_ref!(slf, __getattr__, arg) }) } Some(wrap::) @@ -484,17 +482,14 @@ where where T: for<'p> PyObjectRichcmpProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); let arg = py.from_borrowed_ptr::(arg); - let borrowed_slf = slf.try_borrow()?; let op = extract_op(op)?; let arg = arg.extract()?; - let result = borrowed_slf.__richcmp__(arg, op).into(); - callback::convert(py, result) + + slf.try_borrow()?.__richcmp__(arg, op).into() }) } Some(wrap::) diff --git a/src/class/buffer.rs b/src/class/buffer.rs index d812cbfb..7b27ef15 100644 --- a/src/class/buffer.rs +++ b/src/class/buffer.rs @@ -5,8 +5,7 @@ //! For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html) //! c-api use crate::err::PyResult; -use crate::gil::GILPool; -use crate::{callback, ffi, run_callback, PyCell, PyClass, PyRefMut}; +use crate::{ffi, PyCell, PyClass, PyRefMut}; use std::os::raw::c_int; /// Buffer protocol interface @@ -91,12 +90,9 @@ where where T: for<'p> PyBufferGetBufferProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); - let result = T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).into(); - callback::convert(py, result) + T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).into() }) } Some(wrap::) @@ -126,12 +122,9 @@ where where T: for<'p> PyBufferReleaseBufferProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); - let result = T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).into(); - crate::callback::convert(py, result) + T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).into() }) } Some(wrap::) diff --git a/src/class/macros.rs b/src/class/macros.rs index f96611b7..7d5b0539 100644 --- a/src/class/macros.rs +++ b/src/class/macros.rs @@ -8,11 +8,9 @@ macro_rules! py_unary_func { where T: for<'p> $trait<'p>, { - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); - $crate::callback::convert(py, $call!(slf, $f)$(.map($conv))?) + $call!(slf, $f)$(.map($conv))? }) } Some(wrap::<$class>) @@ -34,14 +32,12 @@ macro_rules! py_unarys_func { where T: for<'p> $trait<'p>, { - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); let borrow = ::try_from_pycell(slf) .map_err(|e| e.into())?; - let res = $class::$f(borrow).into(); - $crate::callback::convert(py, res $(.map($conv))?) + + $class::$f(borrow).into()$(.map($conv))? }) } Some(wrap::<$class>) @@ -71,12 +67,10 @@ macro_rules! py_binary_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg); - $crate::callback::convert(py, $call!(slf, $f, arg)$(.map($conv))?) + $call!(slf, $f, arg)$(.map($conv))? }) } Some(wrap::<$class>) @@ -101,14 +95,11 @@ macro_rules! py_binary_num_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let lhs = py.from_borrowed_ptr::<$crate::PyAny>(lhs); let rhs = py.from_borrowed_ptr::<$crate::PyAny>(rhs); - let result = $class::$f(lhs.extract()?, rhs.extract()?).into(); - $crate::callback::convert(py, result) + $class::$f(lhs.extract()?, rhs.extract()?).into() }) } Some(wrap::<$class>) @@ -127,16 +118,12 @@ macro_rules! py_binary_reverse_num_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { // Swap lhs <-> rhs let slf = py.from_borrowed_ptr::<$crate::PyCell>(rhs); let arg = py.from_borrowed_ptr::<$crate::PyAny>(lhs); - $crate::callback::convert( - py, - $class::$f(&*slf.try_borrow()?, arg.extract()?).into(), - ) + + $class::$f(&*slf.try_borrow()?, arg.extract()?).into() }) } Some(wrap::<$class>) @@ -156,10 +143,7 @@ macro_rules! py_binary_self_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf_ = py.from_borrowed_ptr::<$crate::PyCell>(slf); let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg); call_mut!(slf_, $f, arg)?; @@ -186,11 +170,9 @@ macro_rules! py_ssizearg_func { where T: for<'p> $trait<'p>, { - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); - $crate::callback::convert(py, $call!(slf, $f; arg.into())) + $call!(slf, $f; arg.into()) }) } Some(wrap::<$class>) @@ -210,10 +192,7 @@ macro_rules! py_ternary_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); let arg1 = py .from_borrowed_ptr::<$crate::types::PyAny>(arg1) @@ -222,7 +201,7 @@ macro_rules! py_ternary_func { .from_borrowed_ptr::<$crate::types::PyAny>(arg2) .extract()?; - $crate::callback::convert(py, slf.try_borrow()?.$f(arg1, arg2).into()) + slf.try_borrow()?.$f(arg1, arg2).into() }) } @@ -246,10 +225,7 @@ macro_rules! py_ternary_num_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let arg1 = py .from_borrowed_ptr::<$crate::types::PyAny>(arg1) .extract()?; @@ -260,8 +236,7 @@ macro_rules! py_ternary_num_func { .from_borrowed_ptr::<$crate::types::PyAny>(arg3) .extract()?; - let result = $class::$f(arg1, arg2, arg3).into(); - $crate::callback::convert(py, result) + $class::$f(arg1, arg2, arg3).into() }) } @@ -282,16 +257,13 @@ macro_rules! py_ternary_reverse_num_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { // Swap lhs <-> rhs let slf = py.from_borrowed_ptr::<$crate::PyCell>(arg2); - let slf = slf.try_borrow()?; let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1); let arg2 = py.from_borrowed_ptr::<$crate::PyAny>(arg3); - let result = $class::$f(&*slf, arg1.extract()?, arg2.extract()?).into(); - $crate::callback::convert(py, result) + + $class::$f(&*slf.try_borrow()?, arg1.extract()?, arg2.extract()?).into() }) } Some(wrap::<$class>) @@ -313,10 +285,7 @@ macro_rules! py_dummy_ternary_self_func { T: for<'p> $trait<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf_cell = py.from_borrowed_ptr::<$crate::PyCell>(slf); let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1); call_mut!(slf_cell, $f, arg1)?; @@ -339,10 +308,7 @@ macro_rules! py_func_set { T: for<'p> $trait_name<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell<$generic>>(slf); if value.is_null() { @@ -355,7 +321,7 @@ macro_rules! py_func_set { } else { let name = py.from_borrowed_ptr::<$crate::PyAny>(name); let value = py.from_borrowed_ptr::<$crate::PyAny>(value); - crate::callback::convert(py, call_mut!(slf, $fn_set, name, value)) + call_mut!(slf, $fn_set, name, value) } }) } @@ -375,16 +341,13 @@ macro_rules! py_func_del { U: for<'p> $trait_name<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { if value.is_null() { let slf = py.from_borrowed_ptr::<$crate::PyCell>(slf); let name = py .from_borrowed_ptr::<$crate::types::PyAny>(name) .extract()?; - $crate::callback::convert(py, slf.try_borrow_mut()?.$fn_del(name).into()) + slf.try_borrow_mut()?.$fn_del(name).into() } else { Err(PyErr::new::( "Subscript assignment not supported", @@ -408,20 +371,16 @@ macro_rules! py_func_set_del { T: for<'p> $trait1<'p> + for<'p> $trait2<'p>, { use $crate::ObjectProtocol; - - let pool = $crate::GILPool::new(); - let py = pool.python(); - $crate::run_callback(py, || { + $crate::callback_body!(py, { let slf = py.from_borrowed_ptr::<$crate::PyCell<$generic>>(slf); let name = py.from_borrowed_ptr::<$crate::PyAny>(name); - let result = if value.is_null() { + if value.is_null() { call_mut!(slf, $fn_del, name) } else { let value = py.from_borrowed_ptr::<$crate::PyAny>(value); call_mut!(slf, $fn_set, name, value) - }; - $crate::callback::convert(py, result) + } }) } Some(wrap::<$generic>) diff --git a/src/class/sequence.rs b/src/class/sequence.rs index 4d31ce57..ba8f0d2b 100644 --- a/src/class/sequence.rs +++ b/src/class/sequence.rs @@ -5,9 +5,8 @@ use crate::conversion::{FromPyObject, IntoPy}; use crate::err::{PyErr, PyResult}; -use crate::gil::GILPool; use crate::objectprotocol::ObjectProtocol; -use crate::{callback, exceptions, ffi, run_callback, PyAny, PyCell, PyClass, PyObject}; +use crate::{exceptions, ffi, PyAny, PyCell, PyClass, PyObject}; use std::os::raw::c_int; /// Sequence interface @@ -256,9 +255,7 @@ mod sq_ass_item_impl { where T: for<'p> PySequenceSetItemProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); if value.is_null() { @@ -271,8 +268,7 @@ mod sq_ass_item_impl { let mut slf = slf.try_borrow_mut()?; let value = py.from_borrowed_ptr::(value); let value = value.extract()?; - let result = slf.__setitem__(key.into(), value).into(); - callback::convert(py, result) + slf.__setitem__(key.into(), value).into() }) } Some(wrap::) @@ -305,21 +301,17 @@ mod sq_ass_item_impl { where T: for<'p> PySequenceDelItemProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); - let result = if value.is_null() { + if value.is_null() { slf.borrow_mut().__delitem__(key.into()).into() } else { Err(PyErr::new::(format!( "Item assignment not supported by {:?}", stringify!(T) ))) - }; - - callback::convert(py, result) + } }) } Some(wrap::) @@ -352,20 +344,17 @@ mod sq_ass_item_impl { where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>, { - let pool = GILPool::new(); - let py = pool.python(); - run_callback(py, || { + crate::callback_body!(py, { let slf = py.from_borrowed_ptr::>(slf); - let result = if value.is_null() { + if value.is_null() { call_mut!(slf, __delitem__; key.into()) } else { let value = py.from_borrowed_ptr::(value); let mut slf_ = slf.try_borrow_mut()?; let value = value.extract()?; slf_.__setitem__(key.into(), value).into() - }; - callback::convert(py, result) + } }) } Some(wrap::) diff --git a/src/lib.rs b/src/lib.rs index 883b4362..3e4e1c0a 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,7 +133,6 @@ //! } //! ``` -pub use crate::callback::run_callback; pub use crate::class::*; pub use crate::conversion::{ AsPyPointer, FromPy, FromPyObject, FromPyPointer, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto, diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index 82796334..a708fdea 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -1,11 +1,11 @@ -error[E0597]: `_pool` does not live long enough +error[E0597]: `pool` does not live long enough --> $DIR/static_ref.rs:9:1 | 9 | #[pymethods] - | ^^^^^^^^^^^- - | | | - | | `_pool` dropped here while still borrowed + | ^^^^^^^^^^^^ + | | | borrowed value does not live long enough - | cast requires that `_pool` is borrowed for `'static` + | `pool` dropped here while still borrowed + | cast requires that `pool` is borrowed for `'static` | - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)