Merge pull request #901 from davidhewitt/simplify-callbacks

Simplify callback code using callback_body! macro
This commit is contained in:
Yuji Kanagawa 2020-05-05 12:25:03 +09:00 committed by GitHub
commit 9f1861034b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 200 deletions

View file

@ -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::<pyo3::types::PyTuple>(_args);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body
pyo3::callback::convert(_py, _result)
})
}
}

View file

@ -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::<pyo3::types::PyTuple>(_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::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_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<syn::Ident> = 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::<pyo3::types::PyTuple>(_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::<pyo3::types::PyTuple>(_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::<pyo3::types::PyTuple>(_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::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
pyo3::callback::convert(_py, #getter_impl)
@ -343,9 +315,9 @@ fn impl_call_setter(spec: &FnSpec) -> syn::Result<TokenStream> {
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::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
let _value = _py.from_borrowed_ptr::<pyo3::types::PyAny>(_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

View file

@ -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<T, F>(py: Python, callback: F) -> T
where
F: FnOnce() -> PyResult<T>,
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()
})
}};
}

View file

@ -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::<PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<PyAny>(arg);
callback::convert(py, call_ref!(slf, __getattr__, arg))
call_ref!(slf, __getattr__, arg)
})
}
Some(wrap::<T>)
@ -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::<crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<PyAny>(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::<T>)

View file

@ -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::<PyCell<T>>(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::<T>)
@ -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::<crate::PyCell<T>>(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::<T>)

View file

@ -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<T>>(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<T>>(slf);
let borrow = <T::Receiver>::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<T>>(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<T>>(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<T>>(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<T>>(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<T>>(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<T>>(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<T>>(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<U>>(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::<exceptions::NotImplementedError, _>(
"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>)

View file

@ -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::<PyCell<T>>(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::<PyAny>(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::<T>)
@ -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::<PyCell<T>>(slf);
let result = if value.is_null() {
if value.is_null() {
slf.borrow_mut().__delitem__(key.into()).into()
} else {
Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
"Item assignment not supported by {:?}",
stringify!(T)
)))
};
callback::convert(py, result)
}
})
}
Some(wrap::<T>)
@ -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::<PyCell<T>>(slf);
let result = if value.is_null() {
if value.is_null() {
call_mut!(slf, __delitem__; key.into())
} else {
let value = py.from_borrowed_ptr::<PyAny>(value);
let mut slf_ = slf.try_borrow_mut()?;
let value = value.extract()?;
slf_.__setitem__(key.into(), value).into()
};
callback::convert(py, result)
}
})
}
Some(wrap::<T>)

View file

@ -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,

View file

@ -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)