Modify CallbackConverter so that it can deal with try_borrow well

This commit is contained in:
kngwyu 2020-02-22 20:01:08 +09:00
parent 043b13046a
commit c2a40fbf70
11 changed files with 212 additions and 264 deletions

View File

@ -221,8 +221,7 @@ fn function_c_wrapper(name: &Ident, spec: &method::FnSpec<'_>) -> TokenStream {
#body #body
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} }

View File

@ -115,8 +115,7 @@ fn impl_wrap_common(
pyo3::derive_utils::IntoPyResult::into_py_result(#body) pyo3::derive_utils::IntoPyResult::into_py_result(#body)
}; };
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} else { } else {
@ -138,8 +137,7 @@ fn impl_wrap_common(
#body #body
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} }
@ -169,8 +167,7 @@ pub fn impl_proto_wrap(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
#body #body
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} }
@ -237,8 +234,7 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
#body #body
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} }
@ -267,8 +263,7 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
#body #body
pyo3::callback::cb_convert( pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::PyObjectCallbackConverter, _py, _result)
} }
} }
} }

View File

@ -10,53 +10,62 @@ use crate::{IntoPy, PyObject, Python};
use std::os::raw::c_int; use std::os::raw::c_int;
use std::{isize, ptr}; use std::{isize, ptr};
pub trait CallbackConverter<S> { /// Convert the result of callback function into the appropriate return value.
type R; pub trait CallbackConverter {
type Source;
type Result;
const ERR_VALUE: Self::Result;
fn convert(s: S, p: Python) -> Self::R; fn convert(s: Self::Source, py: Python) -> Self::Result;
fn error_value() -> Self::R;
}
pub struct PyObjectCallbackConverter;
impl<S> CallbackConverter<S> for PyObjectCallbackConverter
where
S: IntoPy<PyObject>,
{
type R = *mut ffi::PyObject;
fn convert(val: S, py: Python) -> *mut ffi::PyObject {
val.into_py(py).into_ptr()
}
#[inline] #[inline]
fn error_value() -> *mut ffi::PyObject { fn convert_result(py: Python, value: PyResult<Self::Source>) -> Self::Result {
ptr::null_mut() match value {
Ok(val) => Self::convert(val, py),
Err(e) => {
e.restore(py);
Self::ERR_VALUE
}
}
}
}
pub struct PyObjectCallbackConverter<T>(pub std::marker::PhantomData<T>);
impl<T> CallbackConverter for PyObjectCallbackConverter<T>
where
T: IntoPy<PyObject>,
{
type Source = T;
type Result = *mut ffi::PyObject;
const ERR_VALUE: Self::Result = ptr::null_mut();
fn convert(s: Self::Source, py: Python) -> Self::Result {
s.into_py(py).into_ptr()
} }
} }
pub struct BoolCallbackConverter; pub struct BoolCallbackConverter;
impl CallbackConverter<bool> for BoolCallbackConverter { impl CallbackConverter for BoolCallbackConverter {
type R = c_int; type Source = bool;
type Result = c_int;
const ERR_VALUE: Self::Result = -1;
#[inline] #[inline]
fn convert(val: bool, _py: Python) -> c_int { fn convert(s: Self::Source, _py: Python) -> Self::Result {
val as c_int s as c_int
}
#[inline]
fn error_value() -> c_int {
-1
} }
} }
pub struct LenResultConverter; pub struct LenResultConverter;
impl CallbackConverter<usize> for LenResultConverter { impl CallbackConverter for LenResultConverter {
type R = isize; type Source = usize;
type Result = isize;
const ERR_VALUE: Self::Result = -1;
fn convert(val: usize, py: Python) -> isize { fn convert(val: Self::Source, py: Python) -> Self::Result {
if val <= (isize::MAX as usize) { if val <= (isize::MAX as usize) {
val as isize val as isize
} else { } else {
@ -64,27 +73,19 @@ impl CallbackConverter<usize> for LenResultConverter {
-1 -1
} }
} }
#[inline]
fn error_value() -> isize {
-1
}
} }
pub struct UnitCallbackConverter; pub struct UnitCallbackConverter;
impl CallbackConverter<()> for UnitCallbackConverter { impl CallbackConverter for UnitCallbackConverter {
type R = c_int; type Source = ();
type Result = c_int;
const ERR_VALUE: Self::Result = -1;
#[inline] #[inline]
fn convert(_: (), _: Python) -> c_int { fn convert(_s: Self::Source, _py: Python) -> Self::Result {
0 0
} }
#[inline]
fn error_value() -> c_int {
-1
}
} }
pub trait WrappingCastTo<T> { pub trait WrappingCastTo<T> {
@ -112,13 +113,15 @@ wrapping_cast!(i32, Py_hash_t);
wrapping_cast!(isize, Py_hash_t); wrapping_cast!(isize, Py_hash_t);
wrapping_cast!(i64, Py_hash_t); wrapping_cast!(i64, Py_hash_t);
pub struct HashConverter; pub struct HashConverter<T>(pub std::marker::PhantomData<T>);
impl<T> CallbackConverter<T> for HashConverter impl<T> CallbackConverter for HashConverter<T>
where where
T: WrappingCastTo<Py_hash_t>, T: WrappingCastTo<Py_hash_t>,
{ {
type R = Py_hash_t; type Source = T;
type Result = Py_hash_t;
const ERR_VALUE: Self::Result = -1;
#[inline] #[inline]
fn convert(val: T, _py: Python) -> Py_hash_t { fn convert(val: T, _py: Python) -> Py_hash_t {
@ -129,23 +132,30 @@ where
hash hash
} }
} }
#[inline]
fn error_value() -> Py_hash_t {
-1
}
} }
// Short hands methods for macros
#[inline] #[inline]
pub unsafe fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::R pub fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::Result
where where
C: CallbackConverter<T>, C: CallbackConverter<Source = T>,
{ {
match value { C::convert_result(py, value)
Ok(val) => C::convert(val, py),
Err(e) => {
e.restore(py);
C::error_value()
} }
#[inline]
pub fn cb_obj_convert<T: IntoPy<PyObject>>(
py: Python,
value: PyResult<T>,
) -> <PyObjectCallbackConverter<T> as CallbackConverter>::Result {
PyObjectCallbackConverter::<T>::convert_result(py, value)
} }
#[inline]
pub unsafe fn cb_err<C>(_c: C, py: Python, err: impl Into<crate::PyErr>) -> C::Result
where
C: CallbackConverter,
{
err.into().restore(py);
C::ERR_VALUE
} }

View File

@ -233,8 +233,13 @@ where
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf); let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<crate::types::PyAny>(arg); let arg = py.from_borrowed_ptr::<crate::types::PyAny>(arg);
let result = call_ref!(slf, __getattr__, arg); call_ref_with_converter!(
crate::callback::cb_convert(PyObjectCallbackConverter, py, result) slf,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData),
py,
__getattr__,
arg
)
} }
Some(wrap::<T>) Some(wrap::<T>)
} }
@ -355,8 +360,7 @@ where
py_unary_func!( py_unary_func!(
PyObjectStrProtocol, PyObjectStrProtocol,
T::__str__, T::__str__,
<T as PyObjectStrProtocol>::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -380,8 +384,7 @@ where
py_unary_func!( py_unary_func!(
PyObjectReprProtocol, PyObjectReprProtocol,
T::__repr__, T::__repr__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -444,8 +447,7 @@ where
py_unary_func!( py_unary_func!(
PyObjectHashProtocol, PyObjectHashProtocol,
T::__hash__, T::__hash__,
isize, HashConverter::<isize>(std::marker::PhantomData),
HashConverter,
ffi::Py_hash_t ffi::Py_hash_t
) )
} }
@ -470,7 +472,6 @@ where
py_unary_func!( py_unary_func!(
PyObjectBoolProtocol, PyObjectBoolProtocol,
T::__bool__, T::__bool__,
bool,
BoolCallbackConverter, BoolCallbackConverter,
c_int c_int
) )

View File

@ -87,8 +87,7 @@ where
py_ternary_func!( py_ternary_func!(
PyDescrGetProtocol, PyDescrGetProtocol,
T::__get__, T::__get__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -109,13 +108,7 @@ where
T: for<'p> PyDescrSetProtocol<'p>, T: for<'p> PyDescrSetProtocol<'p>,
{ {
fn tp_descr_set() -> Option<ffi::descrsetfunc> { fn tp_descr_set() -> Option<ffi::descrsetfunc> {
py_ternary_func!( py_ternary_func!(PyDescrSetProtocol, T::__set__, UnitCallbackConverter, c_int)
PyDescrSetProtocol,
T::__set__,
(),
UnitCallbackConverter,
c_int
)
} }
} }

View File

@ -80,8 +80,7 @@ where
py_unary_refmut_func!( py_unary_refmut_func!(
PyIterIterProtocol, PyIterIterProtocol,
T::__iter__, T::__iter__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -108,21 +107,22 @@ where
py_unary_refmut_func!( py_unary_refmut_func!(
PyIterNextProtocol, PyIterNextProtocol,
T::__next__, T::__next__,
Option<T::Success>, IterNextConverter::<T::Success>(std::marker::PhantomData)
IterNextConverter
) )
} }
} }
struct IterNextConverter; struct IterNextConverter<T>(std::marker::PhantomData<T>);
impl<T> CallbackConverter<Option<T>> for IterNextConverter impl<T> CallbackConverter for IterNextConverter<T>
where where
T: IntoPy<PyObject>, T: IntoPy<PyObject>,
{ {
type R = *mut ffi::PyObject; type Source = Option<T>;
type Result = *mut ffi::PyObject;
const ERR_VALUE: Self::Result = ptr::null_mut();
fn convert(val: Option<T>, py: Python) -> *mut ffi::PyObject { fn convert(val: Self::Source, py: Python) -> Self::Result {
match val { match val {
Some(val) => val.into_py(py).into_ptr(), Some(val) => val.into_py(py).into_ptr(),
None => unsafe { None => unsafe {
@ -131,9 +131,4 @@ where
}, },
} }
} }
#[inline]
fn error_value() -> *mut ffi::PyObject {
ptr::null_mut()
}
} }

View File

@ -3,22 +3,21 @@
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_unary_func { macro_rules! py_unary_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $conv: expr) => {
py_unary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject);
};
// Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $conv: expr, $ret_type:ty) => {
py_unary_func!( py_unary_func!(
$trait, $trait,
$class::$f, $class::$f,
$res_type,
$conv, $conv,
*mut $crate::ffi::PyObject $ret_type,
call_ref_with_converter
); );
}; };
// Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr, $ret_type:ty) => {
py_unary_func!($trait, $class::$f, $res_type, $conv, $ret_type, call_ref);
};
($trait: ident, ($trait: ident,
$class:ident :: $f:ident, $class:ident :: $f:ident,
$res_type:ty,
$conv: expr, $conv: expr,
$ret_type: ty, $ret_type: ty,
$call: ident $call: ident
@ -30,8 +29,7 @@ macro_rules! py_unary_func {
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py); let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf); let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let res = $call!(slf, $f); $call!(slf, $conv, py, $f)
$crate::callback::cb_convert($conv, py, res.map(|x| x))
} }
Some(wrap::<$class>) Some(wrap::<$class>)
}}; }};
@ -40,7 +38,7 @@ macro_rules! py_unary_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_unary_refmut_func { macro_rules! py_unary_refmut_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject
where where
T: for<'p> $trait<'p>, T: for<'p> $trait<'p>,
@ -76,20 +74,14 @@ macro_rules! py_len_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_binary_func { macro_rules! py_binary_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_binary_func!( py_binary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject)
$trait,
$class::$f,
$res_type,
$conv,
*mut $crate::ffi::PyObject
)
}; };
// Use call_ref! by default // Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr, $return:ty) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr, $return:ty) => {{
py_binary_func!($trait, $class::$f, $res_type, $conv, $return, call_ref) py_binary_func!($trait, $class::$f, $conv, $return, call_ref_with_converter)
}}; }};
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr, $return:ty, $call:ident) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr, $return:ty, $call:ident) => {{
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return
where where
T: for<'p> $trait<'p>, T: for<'p> $trait<'p>,
@ -99,8 +91,7 @@ macro_rules! py_binary_func {
let _pool = $crate::GILPool::new(py); let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf); let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<$crate::types::PyAny>(arg); let arg = py.from_borrowed_ptr::<$crate::types::PyAny>(arg);
let result = $call!(slf, $f, arg); $call!(slf, $conv, py, $f, arg)
$crate::callback::cb_convert($conv, py, result)
} }
Some(wrap::<$class>) Some(wrap::<$class>)
}}; }};
@ -109,7 +100,7 @@ macro_rules! py_binary_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_binary_num_func { macro_rules! py_binary_num_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<T>( unsafe extern "C" fn wrap<T>(
lhs: *mut ffi::PyObject, lhs: *mut ffi::PyObject,
rhs: *mut ffi::PyObject, rhs: *mut ffi::PyObject,
@ -137,7 +128,7 @@ macro_rules! py_binary_num_func {
} }
// NOTE(kngwyu): // NOTE(kngwyu):
// Now(2020 2/9) This macro is used only for inplace operation so I used call_refmut here. // Now(2020 2/9) This macro is used only for inplace operation so I used call_mut here.
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_binary_self_func { macro_rules! py_binary_self_func {
@ -155,7 +146,7 @@ macro_rules! py_binary_self_func {
let _pool = $crate::GILPool::new(py); let _pool = $crate::GILPool::new(py);
let slf_ = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf); let slf_ = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<$crate::types::PyAny>(arg); let arg = py.from_borrowed_ptr::<$crate::types::PyAny>(arg);
let result = call_refmut!(slf_, $f, arg); let result = call_mut!(slf_, $f, arg);
match result { match result {
Ok(_) => { Ok(_) => {
ffi::Py_INCREF(slf); ffi::Py_INCREF(slf);
@ -172,16 +163,15 @@ macro_rules! py_binary_self_func {
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_ssizearg_func { macro_rules! py_ssizearg_func {
// Use call_ref! by default // Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_ssizearg_func!( py_ssizearg_func!(
$trait, $trait,
$class::$f, $class::$f,
$res_type,
$conv, $conv,
call_ref call_ref_with_converter
) )
}; };
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr, $call:ident) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr, $call:ident) => {{
unsafe extern "C" fn wrap<T>( unsafe extern "C" fn wrap<T>(
slf: *mut ffi::PyObject, slf: *mut ffi::PyObject,
arg: $crate::ffi::Py_ssize_t, arg: $crate::ffi::Py_ssize_t,
@ -192,8 +182,7 @@ macro_rules! py_ssizearg_func {
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py); let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf); let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let result = $call!(slf, $f ; arg.into()); $call!(slf, $conv, py, $f ;arg.into())
$crate::callback::cb_convert($conv, py, result)
} }
Some(wrap::<$class>) Some(wrap::<$class>)
}}; }};
@ -202,16 +191,10 @@ macro_rules! py_ssizearg_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_ternary_func { macro_rules! py_ternary_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_ternary_func!( py_ternary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject);
$trait,
$class::$f,
$res_type,
$conv,
*mut $crate::ffi::PyObject
);
}; };
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr, $return_type:ty) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr, $return_type:ty) => {{
unsafe extern "C" fn wrap<T>( unsafe extern "C" fn wrap<T>(
slf: *mut $crate::ffi::PyObject, slf: *mut $crate::ffi::PyObject,
arg1: *mut $crate::ffi::PyObject, arg1: *mut $crate::ffi::PyObject,
@ -228,8 +211,7 @@ macro_rules! py_ternary_func {
let arg1 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg1); let arg1 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg2); let arg2 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg2);
let result = call_ref!(slf, $f, arg1, arg2); call_ref_with_converter!(slf, $conv, py, $f, arg1, arg2)
$crate::callback::cb_convert($conv, py, result)
} }
Some(wrap::<T>) Some(wrap::<T>)
@ -239,7 +221,7 @@ macro_rules! py_ternary_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_ternary_num_func { macro_rules! py_ternary_num_func {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<T>( unsafe extern "C" fn wrap<T>(
arg1: *mut $crate::ffi::PyObject, arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject, arg2: *mut $crate::ffi::PyObject,
@ -292,7 +274,7 @@ macro_rules! py_ternary_self_func {
let slf_cell = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf); let slf_cell = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg1 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg1); let arg1 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg2); let arg2 = py.from_borrowed_ptr::<$crate::types::PyAny>(arg2);
let result = call_refmut!(slf_cell, $f, arg1, arg2); let result = call_mut!(slf_cell, $f, arg1, arg2);
match result { match result {
Ok(_) => slf, Ok(_) => slf,
Err(e) => e.restore_and_null(py), Err(e) => e.restore_and_null(py),
@ -328,7 +310,7 @@ macro_rules! py_func_set {
} else { } else {
let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name); let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name);
let value = py.from_borrowed_ptr::<$crate::types::PyAny>(value); let value = py.from_borrowed_ptr::<$crate::types::PyAny>(value);
call_refmut!(slf, $fn_set, name, value) call_mut!(slf, $fn_set, name, value)
}; };
match result { match result {
Ok(_) => 0, Ok(_) => 0,
@ -359,7 +341,7 @@ macro_rules! py_func_del {
let slf = py.from_borrowed_ptr::<$crate::PyCell<U>>(slf); let slf = py.from_borrowed_ptr::<$crate::PyCell<U>>(slf);
let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name); let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name);
call_refmut!(slf, $fn_del, name) call_mut!(slf, $fn_del, name)
} else { } else {
Err(PyErr::new::<exceptions::NotImplementedError, _>( Err(PyErr::new::<exceptions::NotImplementedError, _>(
"Subscript assignment not supported", "Subscript assignment not supported",
@ -393,10 +375,10 @@ macro_rules! py_func_set_del {
let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name); let name = py.from_borrowed_ptr::<$crate::types::PyAny>(name);
let result = if value.is_null() { let result = if value.is_null() {
call_refmut!(slf, $fn_del, name) call_mut!(slf, $fn_del, name)
} else { } else {
let value = py.from_borrowed_ptr::<$crate::types::PyAny>(value); let value = py.from_borrowed_ptr::<$crate::types::PyAny>(value);
call_refmut!(slf, $fn_set, name, value) call_mut!(slf, $fn_set, name, value)
}; };
match result { match result {
Ok(_) => 0, Ok(_) => 0,
@ -407,33 +389,48 @@ macro_rules! py_func_set_del {
}}; }};
} }
// Utitlities for extract arguments + call method for PyCell<T> macro_rules! _call_impl {
macro_rules! call_ref { ($slf: ident, $fn: ident $(; $args: expr)*) => { $slf.$fn($($args,)*).into() };
($slf: expr, $fn: ident $(; $args: expr)*) => { ($slf: ident, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow_unguarded() {
Ok(slf) => slf.$fn($($args,)*).into(),
Err(e) => Err(e.into()),
}
};
($slf: expr, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
match $raw_arg.extract() { match $raw_arg.extract() {
Ok(arg) => call_ref!($slf, $fn $(,$raw_args)* $(;$args)* ;arg), Ok(arg) => _call_impl!($slf, $fn $(,$raw_args)* $(;$args)* ;arg),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
}; };
} }
macro_rules! call_refmut { macro_rules! call_ref {
($slf: expr, $fn: ident $(; $args: expr)*) => { ($slf: expr, $fn: ident $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow_mut_unguarded() { match $slf.try_borrow() {
Ok(slf) => slf.$fn($($args,)*).into(), Ok(slf) => _call_impl!(slf, $fn $(,$raw_args)* $(;$args)*),
Err(e) => Err(e.into()),
}
};
($slf: expr, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
match $raw_arg.extract() {
Ok(arg) => call_refmut!($slf, $fn $(,$raw_args)* $(;$args)* ;arg),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
}; };
} }
macro_rules! call_ref_with_converter {
($slf: expr, $conv: expr, $py: ident, $fn: ident $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow() {
Ok(slf) => $crate::callback::cb_convert($conv, $py, _call_impl!(slf, $fn $(,$raw_args)* $(;$args)*)),
Err(e) => $crate::callback::cb_err($conv, $py, e)
}
};
}
macro_rules! call_mut {
($slf: expr, $fn: ident $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow_mut() {
Ok(mut slf) => _call_impl!(slf, $fn $(,$raw_args)* $(;$args)*),
Err(e) => Err(e.into()),
}
};
}
macro_rules! call_mut_with_converter {
($slf: expr, $conv: expr, $py: ident, $fn: ident $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow_mut() {
Ok(mut slf) => $crate::callback::cb_convert($conv, $py, _call_impl!(slf, $fn $(,$raw_args)* $(;$args)*)),
Err(e) => $crate::callback::cb_err($conv, $py, e)
}
};
}

View File

@ -167,8 +167,7 @@ where
py_binary_func!( py_binary_func!(
PyMappingGetItemProtocol, PyMappingGetItemProtocol,
T::__getitem__, T::__getitem__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }

View File

@ -764,8 +764,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberAddProtocol, PyNumberAddProtocol,
T::__add__, T::__add__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -791,8 +790,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberSubProtocol, PyNumberSubProtocol,
T::__sub__, T::__sub__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -818,8 +816,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberMulProtocol, PyNumberMulProtocol,
T::__mul__, T::__mul__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -845,8 +842,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberMatmulProtocol, PyNumberMatmulProtocol,
T::__matmul__, T::__matmul__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -872,8 +868,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberTruedivProtocol, PyNumberTruedivProtocol,
T::__truediv__, T::__truediv__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -899,8 +894,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberFloordivProtocol, PyNumberFloordivProtocol,
T::__floordiv__, T::__floordiv__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -926,8 +920,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberModProtocol, PyNumberModProtocol,
T::__mod__, T::__mod__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -953,8 +946,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberDivmodProtocol, PyNumberDivmodProtocol,
T::__divmod__, T::__divmod__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -980,8 +972,7 @@ where
py_ternary_num_func!( py_ternary_num_func!(
PyNumberPowProtocol, PyNumberPowProtocol,
T::__pow__, T::__pow__,
<T as PyNumberPowProtocol>::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1007,8 +998,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberLShiftProtocol, PyNumberLShiftProtocol,
T::__lshift__, T::__lshift__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1034,8 +1024,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberRShiftProtocol, PyNumberRShiftProtocol,
T::__rshift__, T::__rshift__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1061,8 +1050,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberAndProtocol, PyNumberAndProtocol,
T::__and__, T::__and__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1088,8 +1076,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberXorProtocol, PyNumberXorProtocol,
T::__xor__, T::__xor__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1115,8 +1102,7 @@ where
py_binary_num_func!( py_binary_num_func!(
PyNumberOrProtocol, PyNumberOrProtocol,
T::__or__, T::__or__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1620,8 +1606,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberNegProtocol, PyNumberNegProtocol,
T::__neg__, T::__neg__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1647,8 +1632,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberPosProtocol, PyNumberPosProtocol,
T::__pos__, T::__pos__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1674,8 +1658,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberAbsProtocol, PyNumberAbsProtocol,
T::__abs__, T::__abs__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1701,8 +1684,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberInvertProtocol, PyNumberInvertProtocol,
T::__invert__, T::__invert__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1728,8 +1710,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberIntProtocol, PyNumberIntProtocol,
T::__int__, T::__int__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1755,8 +1736,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberFloatProtocol, PyNumberFloatProtocol,
T::__float__, T::__float__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -1782,8 +1762,7 @@ where
py_unary_func!( py_unary_func!(
PyNumberIndexProtocol, PyNumberIndexProtocol,
T::__index__, T::__index__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }

View File

@ -153,8 +153,7 @@ where
py_unary_func!( py_unary_func!(
PyAsyncAwaitProtocol, PyAsyncAwaitProtocol,
T::__await__, T::__await__,
<T as PyAsyncAwaitProtocol>::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -181,8 +180,7 @@ where
py_unary_func!( py_unary_func!(
PyAsyncAiterProtocol, PyAsyncAiterProtocol,
T::__aiter__, T::__aiter__,
<T as PyAsyncAiterProtocol>::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -206,17 +204,20 @@ mod anext {
use crate::IntoPyPointer; use crate::IntoPyPointer;
use crate::Python; use crate::Python;
use crate::{ffi, IntoPy, PyObject}; use crate::{ffi, IntoPy, PyObject};
use std::marker::PhantomData;
use std::ptr; use std::ptr;
pub struct IterANextResultConverter; struct IterANextResultConverter<T>(PhantomData<T>);
impl<T> CallbackConverter<Option<T>> for IterANextResultConverter impl<T> CallbackConverter for IterANextResultConverter<T>
where where
T: IntoPy<PyObject>, T: IntoPy<PyObject>,
{ {
type R = *mut ffi::PyObject; type Source = Option<T>;
type Result = *mut ffi::PyObject;
const ERR_VALUE: Self::Result = ptr::null_mut();
fn convert(val: Option<T>, py: Python) -> *mut ffi::PyObject { fn convert(val: Self::Source, py: Python) -> Self::Result {
match val { match val {
Some(val) => val.into_py(py).into_ptr(), Some(val) => val.into_py(py).into_ptr(),
None => unsafe { None => unsafe {
@ -225,11 +226,6 @@ mod anext {
}, },
} }
} }
#[inline]
fn error_value() -> *mut ffi::PyObject {
ptr::null_mut()
}
} }
impl<T> PyAsyncAnextProtocolImpl for T impl<T> PyAsyncAnextProtocolImpl for T
@ -241,10 +237,9 @@ mod anext {
py_unary_func!( py_unary_func!(
PyAsyncAnextProtocol, PyAsyncAnextProtocol,
T::__anext__, T::__anext__,
Option<T::Success>, IterANextResultConverter::<T::Success>(std::marker::PhantomData),
IterANextResultConverter,
*mut crate::ffi::PyObject, *mut crate::ffi::PyObject,
call_refmut call_mut_with_converter
) )
} }
} }

View File

@ -202,8 +202,7 @@ where
py_ssizearg_func!( py_ssizearg_func!(
PySequenceGetItemProtocol, PySequenceGetItemProtocol,
T::__getitem__, T::__getitem__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -283,10 +282,7 @@ mod sq_ass_item_impl {
match result { match result {
Ok(_) => 0, Ok(_) => 0,
Err(e) => { Err(e) => e.restore_and_minus1(py),
e.restore(py);
-1
}
} }
} }
Some(wrap::<T>) Some(wrap::<T>)
@ -334,10 +330,7 @@ mod sq_ass_item_impl {
match result { match result {
Ok(_) => 0, Ok(_) => 0,
Err(e) => { Err(e) => e.restore_and_minus1(py),
e.restore(py);
-1
}
} }
} }
Some(wrap::<T>) Some(wrap::<T>)
@ -375,7 +368,7 @@ mod sq_ass_item_impl {
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf); let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let result = if value.is_null() { let result = if value.is_null() {
call_refmut!(slf, __delitem__; key.into()) call_mut!(slf, __delitem__; key.into())
} else { } else {
let value = py.from_borrowed_ptr::<PyAny>(value); let value = py.from_borrowed_ptr::<PyAny>(value);
match value.extract() { match value.extract() {
@ -388,10 +381,7 @@ mod sq_ass_item_impl {
}; };
match result { match result {
Ok(_) => 0, Ok(_) => 0,
Err(e) => { Err(e) => e.restore_and_minus1(py),
e.restore(py);
-1
}
} }
} }
Some(wrap::<T>) Some(wrap::<T>)
@ -420,7 +410,6 @@ where
py_binary_func!( py_binary_func!(
PySequenceContainsProtocol, PySequenceContainsProtocol,
T::__contains__, T::__contains__,
bool,
BoolCallbackConverter, BoolCallbackConverter,
c_int c_int
) )
@ -448,8 +437,7 @@ where
py_binary_func!( py_binary_func!(
PySequenceConcatProtocol, PySequenceConcatProtocol,
T::__concat__, T::__concat__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -475,8 +463,7 @@ where
py_ssizearg_func!( py_ssizearg_func!(
PySequenceRepeatProtocol, PySequenceRepeatProtocol,
T::__repeat__, T::__repeat__,
T::Success, PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
PyObjectCallbackConverter
) )
} }
} }
@ -502,10 +489,9 @@ where
py_binary_func!( py_binary_func!(
PySequenceInplaceConcatProtocol, PySequenceInplaceConcatProtocol,
T::__inplace_concat__, T::__inplace_concat__,
T, PyObjectCallbackConverter::<T>(std::marker::PhantomData),
PyObjectCallbackConverter,
*mut crate::ffi::PyObject, *mut crate::ffi::PyObject,
call_refmut call_mut_with_converter
) )
} }
} }
@ -531,9 +517,8 @@ where
py_ssizearg_func!( py_ssizearg_func!(
PySequenceInplaceRepeatProtocol, PySequenceInplaceRepeatProtocol,
T::__inplace_repeat__, T::__inplace_repeat__,
T, PyObjectCallbackConverter::<T>(std::marker::PhantomData),
PyObjectCallbackConverter, call_mut_with_converter
call_refmut
) )
} }
} }