Refactor CallbackConverter code

Now shorter and allows use of the ? operator inside callback code
This commit is contained in:
David Hewitt 2020-03-07 09:59:49 +00:00
parent a9357ef8a1
commit d8effb24e8
17 changed files with 519 additions and 825 deletions

View File

@ -63,7 +63,7 @@ impl<'a> FnSpec<'a> {
let is_mut = self
.self_
.expect("impl_borrow_self is called for non-self fn");
crate::utils::borrow_self(is_mut, true)
crate::utils::borrow_self(is_mut)
}
/// Parser function signature and function attributes

View File

@ -221,13 +221,15 @@ fn function_c_wrapper(name: &Ident, spec: &method::FnSpec<'_>) -> TokenStream {
const _LOCATION: &'static str = concat!(stringify!(#name), "()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::convert(_py, _result)
})
}
}
}

View File

@ -83,10 +83,7 @@ pub fn impl_wrap_pyslf(
};
let slf = quote! {
let _cell = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
let _slf: #self_ty = match std::convert::TryFrom::try_from(_cell) {
Ok(_slf) => _slf,
Err(e) => return pyo3::PyErr::from(e).restore_and_null(_py),
};
let _slf: #self_ty = std::convert::TryFrom::try_from(_cell)?;
};
impl_wrap_common(cls, spec, noargs, slf, body)
}
@ -109,13 +106,11 @@ fn impl_wrap_common(
const _LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#python_name), "()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
#slf
let _result = {
pyo3::derive_utils::IntoPyResult::into_py_result(#body)
};
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_py);
#slf
pyo3::callback::convert(_py, #body)
})
}
}
} else {
@ -130,14 +125,16 @@ fn impl_wrap_common(
const _LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#python_name), "()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_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);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::convert(_py, _result)
})
}
}
}
@ -159,15 +156,17 @@ pub fn impl_proto_wrap(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
{
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_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);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::convert(_py, _result)
})
}
}
}
@ -195,16 +194,16 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
match _result.and_then(|init| pyo3::PyClassInitializer::from(init).create_cell(_py)) {
Ok(slf) => slf as _,
Err(e) => e.restore_and_null(_py),
}
let cell = pyo3::PyClassInitializer::from(_result?).create_cell(_py)?;
Ok(cell as *mut pyo3::ffi::PyObject)
})
}
}
}
@ -227,14 +226,16 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
{
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_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);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::convert(_py, _result)
})
}
}
}
@ -257,13 +258,15 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
{
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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
#body
pyo3::callback::cb_obj_convert(_py, _result)
pyo3::callback::convert(_py, _result)
})
}
}
}
@ -305,7 +308,7 @@ pub(crate) fn impl_wrap_getter(
PropertyType::Function(spec) => (spec.python_name.clone(), impl_call_getter(&spec)?),
};
let borrow_self = crate::utils::borrow_self(false, true);
let borrow_self = crate::utils::borrow_self(false);
Ok(quote! {
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> *mut pyo3::ffi::PyObject
@ -313,16 +316,12 @@ pub(crate) fn impl_wrap_getter(
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
let result = pyo3::derive_utils::IntoPyResult::into_py_result(#getter_impl);
match result {
Ok(val) => pyo3::IntoPyPointer::into_ptr(pyo3::IntoPy::<PyObject>::into_py(val, _py)),
Err(e) => e.restore_and_null(_py),
}
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_py);
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
pyo3::callback::convert(_py, #getter_impl)
})
}
})
}
@ -344,9 +343,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)
@ -360,12 +359,12 @@ 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; Ok(()) }))
(name.unraw(), quote!(_slf.#name = _val;))
}
PropertyType::Function(spec) => (spec.python_name.clone(), impl_call_setter(&spec)?),
};
let borrow_self = crate::utils::borrow_self(true, false);
let borrow_self = crate::utils::borrow_self(true);
Ok(quote! {
#[allow(unused_mut)]
unsafe extern "C" fn __wrap(
@ -374,21 +373,14 @@ pub(crate) fn impl_wrap_setter(
{
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py);
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
let _value = _py.from_borrowed_ptr(_value);
let _result = match pyo3::FromPyObject::extract(_value) {
Ok(_val) => {
#setter_impl
}
Err(e) => Err(e)
};
match _result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(_py),
}
pyo3::run_callback(_py, || {
let _pool = pyo3::GILPool::new(_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})
})
}
})
}
@ -462,22 +454,19 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre
let mut _args = _args;
let mut _kwargs = _kwargs;
// Workaround to use the question mark operator without rewriting everything
let _result = (|| {
let (_args, _kwargs) = pyo3::derive_utils::parse_fn_args(
Some(_LOCATION),
PARAMS,
_args,
_kwargs,
#accept_args,
#accept_kwargs,
&mut output
)?;
let (_args, _kwargs) = pyo3::derive_utils::parse_fn_args(
Some(_LOCATION),
PARAMS,
_args,
_kwargs,
#accept_args,
#accept_kwargs,
&mut output
)?;
#(#param_conversion)*
#(#param_conversion)*
#into_result(#body)
})();
let _result = #into_result(#body);
}
}

View File

@ -4,25 +4,14 @@ use proc_macro2::TokenStream;
use quote::quote;
use std::fmt::Display;
pub(crate) fn borrow_self(is_mut: bool, return_null: bool) -> TokenStream {
let ret = if return_null {
quote! { restore_and_null }
} else {
quote! { restore_and_minus1 }
};
pub(crate) fn borrow_self(is_mut: bool) -> TokenStream {
if is_mut {
quote! {
let mut _slf = match _slf.try_borrow_mut() {
Ok(ref_) => ref_,
Err(e) => return pyo3::PyErr::from(e).#ret(_py),
};
let mut _slf = _slf.try_borrow_mut()?;
}
} else {
quote! {
let _slf = match _slf.try_borrow() {
Ok(ref_) => ref_,
Err(e) => return pyo3::PyErr::from(e).#ret(_py),
};
let _slf = _slf.try_borrow()?;
}
}
}

View File

@ -7,89 +7,91 @@ use crate::exceptions::OverflowError;
use crate::ffi::{self, Py_hash_t};
use crate::IntoPyPointer;
use crate::{IntoPy, PyObject, Python};
use std::isize;
use std::os::raw::c_int;
use std::{isize, ptr};
/// A type which can be the return type of a python C-API callback
pub trait PyCallbackOutput: Copy {
/// The error value to return to python if the callback raised an exception
const ERR_VALUE: Self;
}
impl PyCallbackOutput for *mut ffi::PyObject {
const ERR_VALUE: Self = std::ptr::null_mut();
}
impl PyCallbackOutput for libc::c_int {
const ERR_VALUE: Self = -1;
}
impl PyCallbackOutput for ffi::Py_ssize_t {
const ERR_VALUE: Self = -1;
}
impl PyCallbackOutput for () {
const ERR_VALUE: Self = ();
}
/// Convert the result of callback function into the appropriate return value.
///
/// Used by PyO3 macros.
pub trait CallbackConverter {
type Source;
type Result: Copy;
const ERR_VALUE: Self::Result;
pub trait IntoPyCallbackOutput<Target> {
fn convert(self, py: Python) -> PyResult<Target>;
}
fn convert(s: Self::Source, py: Python) -> Self::Result;
#[inline]
fn convert_result(py: Python, value: PyResult<Self::Source>) -> Self::Result {
match value {
Ok(val) => Self::convert(val, py),
Err(e) => {
e.restore(py);
Self::ERR_VALUE
}
}
impl<T, U> IntoPyCallbackOutput<U> for PyResult<T>
where
T: IntoPyCallbackOutput<U>,
{
fn convert(self, py: Python) -> PyResult<U> {
self.and_then(|t| t.convert(py))
}
}
pub struct PyObjectCallbackConverter<T>(pub std::marker::PhantomData<T>);
impl<T> CallbackConverter for PyObjectCallbackConverter<T>
impl<T> IntoPyCallbackOutput<*mut ffi::PyObject> for 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()
fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> {
Ok(self.into_py(py).into_ptr())
}
}
pub struct BoolCallbackConverter;
impl IntoPyCallbackOutput<Self> for *mut ffi::PyObject {
fn convert(self, _: Python) -> PyResult<Self> {
Ok(self)
}
}
impl CallbackConverter for BoolCallbackConverter {
type Source = bool;
type Result = c_int;
const ERR_VALUE: Self::Result = -1;
impl IntoPyCallbackOutput<libc::c_int> for () {
fn convert(self, _: Python) -> PyResult<libc::c_int> {
Ok(0)
}
}
impl IntoPyCallbackOutput<libc::c_int> for bool {
fn convert(self, _: Python) -> PyResult<libc::c_int> {
Ok(self as c_int)
}
}
impl IntoPyCallbackOutput<()> for () {
fn convert(self, _: Python) -> PyResult<()> {
Ok(())
}
}
pub struct LenCallbackOutput(pub usize);
impl IntoPyCallbackOutput<ffi::Py_ssize_t> for LenCallbackOutput {
#[inline]
fn convert(s: Self::Source, _py: Python) -> Self::Result {
s as c_int
}
}
pub struct LenResultConverter;
impl CallbackConverter for LenResultConverter {
type Source = usize;
type Result = isize;
const ERR_VALUE: Self::Result = -1;
fn convert(val: Self::Source, py: Python) -> Self::Result {
if val <= (isize::MAX as usize) {
val as isize
fn convert(self, _py: Python) -> PyResult<ffi::Py_ssize_t> {
if self.0 <= (isize::MAX as usize) {
Ok(self.0 as isize)
} else {
OverflowError::py_err(()).restore(py);
-1
Err(OverflowError::py_err(()))
}
}
}
pub struct UnitCallbackConverter;
impl CallbackConverter for UnitCallbackConverter {
type Source = ();
type Result = c_int;
const ERR_VALUE: Self::Result = -1;
#[inline]
fn convert(_s: Self::Source, _py: Python) -> Self::Result {
0
}
}
pub trait WrappingCastTo<T> {
fn wrapping_cast(self) -> T;
}
@ -115,50 +117,49 @@ wrapping_cast!(i32, Py_hash_t);
wrapping_cast!(isize, Py_hash_t);
wrapping_cast!(i64, Py_hash_t);
pub struct HashConverter<T>(pub std::marker::PhantomData<T>);
pub struct HashCallbackOutput<T>(pub T);
impl<T> CallbackConverter for HashConverter<T>
impl<T> IntoPyCallbackOutput<Py_hash_t> for HashCallbackOutput<T>
where
T: WrappingCastTo<Py_hash_t>,
{
type Source = T;
type Result = Py_hash_t;
const ERR_VALUE: Self::Result = -1;
#[inline]
fn convert(val: T, _py: Python) -> Py_hash_t {
let hash = val.wrapping_cast();
fn convert(self, _py: Python) -> PyResult<Py_hash_t> {
let hash = self.0.wrapping_cast();
if hash == -1 {
-2
Ok(-2)
} else {
hash
Ok(hash)
}
}
}
// Short hands methods for macros
#[doc(hidden)]
#[inline]
pub fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::Result
pub fn convert<T, U>(py: Python, value: T) -> PyResult<U>
where
C: CallbackConverter<Source = T>,
T: IntoPyCallbackOutput<U>,
{
C::convert_result(py, value)
value.convert(py)
}
// Same as cb_convert(PyObjectCallbackConverter<T>, py, value)
#[doc(hidden)]
#[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)
pub fn callback_error<T>() -> T
where
T: PyCallbackOutput,
{
T::ERR_VALUE
}
#[inline]
pub unsafe fn cb_err<C>(_c: C, py: Python, err: impl Into<crate::PyErr>) -> C::Result
#[doc(hidden)]
pub fn run_callback<T, F>(py: Python, callback: F) -> T
where
C: CallbackConverter,
F: FnOnce() -> PyResult<T>,
T: PyCallbackOutput,
{
err.into().restore(py);
C::ERR_VALUE
callback().unwrap_or_else(|e| {
e.restore(py);
T::ERR_VALUE
})
}

View File

@ -8,11 +8,11 @@
//! Parts of the documentation are copied from the respective methods from the
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
use crate::callback::{BoolCallbackConverter, HashConverter, PyObjectCallbackConverter};
use crate::callback::HashCallbackOutput;
use crate::class::methods::PyMethodDef;
use crate::{
exceptions, ffi, FromPyObject, IntoPy, IntoPyPointer, ObjectProtocol, PyAny, PyClass, PyErr,
PyObject, PyResult, Python,
callback, exceptions, ffi, run_callback, FromPyObject, GILPool, IntoPy, ObjectProtocol, PyAny,
PyCell, PyClass, PyErr, PyObject, PyResult, Python,
};
use std::os::raw::c_int;
@ -219,27 +219,23 @@ where
T: for<'p> PyObjectGetAttrProtocol<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
run_callback(py, || {
let _pool = GILPool::new(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);
if existing.is_null() {
// PyObject_HasAttr also tries to get an object and clears the error if it fails
ffi::PyErr_Clear();
} else {
return existing;
}
// Behave like python's __getattr__ (as opposed to __getattribute__) and check
// for existing fields and methods first
let existing = ffi::PyObject_GenericGetAttr(slf, arg);
if existing.is_null() {
// PyObject_HasAttr also tries to get an object and clears the error if it fails
ffi::PyErr_Clear();
} else {
return Ok(existing);
}
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<crate::PyAny>(arg);
call_ref_with_converter!(
slf,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData),
py,
__getattr__,
arg
)
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))
})
}
Some(wrap::<T>)
}
@ -357,11 +353,7 @@ where
T: for<'p> PyObjectStrProtocol<'p>,
{
fn tp_str() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyObjectStrProtocol,
T::__str__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyObjectStrProtocol, T::__str__)
}
}
@ -381,11 +373,7 @@ where
T: for<'p> PyObjectReprProtocol<'p>,
{
fn tp_repr() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyObjectReprProtocol,
T::__repr__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyObjectReprProtocol, T::__repr__)
}
}
@ -447,8 +435,8 @@ where
py_unary_func!(
PyObjectHashProtocol,
T::__hash__,
HashConverter::<isize>(std::marker::PhantomData),
ffi::Py_hash_t
ffi::Py_hash_t,
HashCallbackOutput
)
}
}
@ -469,12 +457,7 @@ where
T: for<'p> PyObjectBoolProtocol<'p>,
{
fn nb_bool() -> Option<ffi::inquiry> {
py_unary_func!(
PyObjectBoolProtocol,
T::__bool__,
BoolCallbackConverter,
c_int
)
py_unary_func!(PyObjectBoolProtocol, T::__bool__, c_int)
}
}
@ -503,26 +486,17 @@ where
T: for<'p> PyObjectRichcmpProtocol<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<PyAny>(arg);
run_callback(py, || {
let _pool = GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<PyAny>(arg);
match slf.try_borrow() {
Ok(borrowed_slf) => {
let res = match extract_op(op) {
Ok(op) => match arg.extract() {
Ok(arg) => borrowed_slf.__richcmp__(arg, op).into(),
Err(e) => Err(e),
},
Err(e) => Err(e),
};
match res {
Ok(val) => val.into_py(py).into_ptr(),
Err(e) => e.restore_and_null(py),
}
}
Err(e) => PyErr::from(e).restore_and_null(py),
}
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)
})
}
Some(wrap::<T>)
}

View File

@ -4,9 +4,9 @@
//!
//! For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
//! c-api
use crate::callback::UnitCallbackConverter;
use crate::err::PyResult;
use crate::{ffi, PyClass, PyRefMut};
use crate::gil::GILPool;
use crate::{callback, ffi, run_callback, PyCell, PyClass, PyRefMut, Python};
use std::os::raw::c_int;
/// Buffer protocol interface
@ -91,14 +91,13 @@ where
where
T: for<'p> PyBufferGetBufferProtocol<'p>,
{
let py = crate::Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let result = slf
.try_borrow_mut()
.map_err(crate::PyErr::from)
.and_then(|slf_mut| T::bf_getbuffer(slf_mut, arg1, arg2).into());
crate::callback::cb_convert(UnitCallbackConverter, py, result)
let py = Python::assume_gil_acquired();
run_callback(py, || {
let _pool = GILPool::new(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)
})
}
Some(wrap::<T>)
}
@ -127,14 +126,13 @@ where
where
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
{
let py = crate::Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
let result = slf
.try_borrow_mut()
.map_err(crate::PyErr::from)
.and_then(|slf_mut| T::bf_releasebuffer(slf_mut, arg1).into());
crate::callback::cb_convert(UnitCallbackConverter, py, result);
let py = Python::assume_gil_acquired();
run_callback(py, || {
let _pool = GILPool::new(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)
})
}
Some(wrap::<T>)
}

View File

@ -5,7 +5,6 @@
//! [Python information](
//! https://docs.python.org/3/reference/datamodel.html#implementing-descriptors)
use crate::callback::{PyObjectCallbackConverter, UnitCallbackConverter};
use crate::class::methods::PyMethodDef;
use crate::err::PyResult;
use crate::types::{PyAny, PyType};
@ -84,11 +83,7 @@ where
T: for<'p> PyDescrGetProtocol<'p>,
{
fn tp_descr_get() -> Option<ffi::descrgetfunc> {
py_ternary_func!(
PyDescrGetProtocol,
T::__get__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_ternary_func!(PyDescrGetProtocol, T::__get__)
}
}
@ -108,7 +103,7 @@ where
T: for<'p> PyDescrSetProtocol<'p>,
{
fn tp_descr_set() -> Option<ffi::descrsetfunc> {
py_ternary_func!(PyDescrSetProtocol, T::__set__, UnitCallbackConverter, c_int)
py_ternary_func!(PyDescrSetProtocol, T::__set__, c_int)
}
}

View File

@ -2,10 +2,9 @@
//! Python Iterator Interface.
//! Trait and support implementation for implementing iterators
use crate::callback::{CallbackConverter, PyObjectCallbackConverter};
use crate::callback::IntoPyCallbackOutput;
use crate::err::PyResult;
use crate::{ffi, IntoPy, IntoPyPointer, PyClass, PyObject, PyRefMut, Python};
use std::ptr;
/// Python Iterator Interface.
///
@ -77,11 +76,7 @@ where
{
#[inline]
fn tp_iter() -> Option<ffi::getiterfunc> {
py_unary_refmut_func!(
PyIterIterProtocol,
T::__iter__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_refmut_func!(PyIterIterProtocol, T::__iter__)
}
}
@ -104,31 +99,20 @@ where
{
#[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> {
py_unary_refmut_func!(
PyIterNextProtocol,
T::__next__,
IterNextConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_refmut_func!(PyIterNextProtocol, T::__next__, IterNextConverter)
}
}
struct IterNextConverter<T>(std::marker::PhantomData<T>);
struct IterNextConverter<T>(Option<T>);
impl<T> CallbackConverter for IterNextConverter<T>
impl<T> IntoPyCallbackOutput<*mut ffi::PyObject> for IterNextConverter<T>
where
T: IntoPy<PyObject>,
{
type Source = Option<T>;
type Result = *mut ffi::PyObject;
const ERR_VALUE: Self::Result = ptr::null_mut();
fn convert(val: Self::Source, py: Python) -> Self::Result {
match val {
Some(val) => val.into_py(py).into_ptr(),
None => unsafe {
ffi::PyErr_SetNone(ffi::PyExc_StopIteration);
ptr::null_mut()
},
fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> {
match self.0 {
Some(val) => Ok(val.into_py(py).into_ptr()),
None => Err(crate::exceptions::StopIteration::py_err(())),
}
}
}

View File

@ -3,51 +3,44 @@
#[macro_export]
#[doc(hidden)]
macro_rules! py_unary_func {
($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!(
$trait,
$class::$f,
$conv,
$ret_type,
call_ref_with_converter
);
};
($trait: ident,
$class:ident :: $f:ident,
$conv: expr,
$ret_type: ty,
$call: ident
) => {{
($trait: ident, $class:ident :: $f:ident, $call:ident, $ret_type: ty $(, $conv:expr)?) => {{
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> $ret_type
where
T: for<'p> $trait<'p>,
{
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
$call!(slf, $conv, py, $f)
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
$crate::callback::convert(py, $call!(slf, $f)$(.map($conv))?)
})
}
Some(wrap::<$class>)
}};
// Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $ret_type:ty $(, $conv:expr)?) => {
py_unary_func!($trait, $class::$f, call_ref, $ret_type $(, $conv)?);
};
($trait:ident, $class:ident :: $f:ident $(, $conv:expr)?) => {
py_unary_func!($trait, $class::$f, call_ref, *mut $crate::ffi::PyObject $(, $conv)?);
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_unary_refmut_func {
($trait:ident, $class:ident :: $f:ident, $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
where
T: for<'p> $trait<'p>,
{
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let res = $class::$f(slf.borrow_mut()).into();
$crate::callback::cb_convert($conv, py, res)
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let res = $class::$f(slf.borrow_mut()).into();
$crate::callback::convert(py, res $(.map($conv))?)
})
}
Some(wrap::<$class>)
}};
@ -56,51 +49,48 @@ macro_rules! py_unary_refmut_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_len_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> $crate::ffi::Py_ssize_t
where
T: for<'p> $trait<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let result = call_ref!(slf, $f);
$crate::callback::cb_convert($conv, py, result)
}
Some(wrap::<$class>)
}};
($trait:ident, $class:ident :: $f:ident) => {
py_unary_func!(
$trait,
$class::$f,
$crate::ffi::Py_ssize_t,
$crate::callback::LenCallbackOutput
)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_binary_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_binary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject)
};
// Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $conv:expr, $return:ty) => {{
py_binary_func!($trait, $class::$f, $conv, $return, call_ref_with_converter)
}};
($trait:ident, $class:ident :: $f:ident, $conv:expr, $return:ty, $call:ident) => {{
($trait:ident, $class:ident :: $f:ident, $return:ty, $call:ident $(, $conv:expr)?) => {{
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return
where
T: for<'p> $trait<'p>,
{
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg);
$call!(slf, $conv, py, $f, arg)
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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))?)
})
}
Some(wrap::<$class>)
}};
($trait:ident, $class:ident :: $f:ident, $return:ty $(, $conv:expr)?) => {
py_binary_func!($trait, $class::$f, $return, call_ref $(, $conv)?)
};
($trait:ident, $class:ident :: $f:ident $(, $conv:expr)?) => {
py_binary_func!($trait, $class::$f, *mut $crate::ffi::PyObject $(, $conv)?)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_binary_num_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
($trait:ident, $class:ident :: $f:ident) => {{
unsafe extern "C" fn wrap<T>(
lhs: *mut ffi::PyObject,
rhs: *mut ffi::PyObject,
@ -110,18 +100,14 @@ macro_rules! py_binary_num_func {
{
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let lhs = py.from_borrowed_ptr::<$crate::PyAny>(lhs);
let rhs = py.from_borrowed_ptr::<$crate::PyAny>(rhs);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let lhs = py.from_borrowed_ptr::<$crate::PyAny>(lhs);
let rhs = py.from_borrowed_ptr::<$crate::PyAny>(rhs);
let result = match lhs.extract() {
Ok(lhs) => match rhs.extract() {
Ok(rhs) => $class::$f(lhs, rhs).into(),
Err(e) => Err(e.into()),
},
Err(e) => Err(e.into()),
};
$crate::callback::cb_convert($conv, py, result)
let result = $class::$f(lhs.extract()?, rhs.extract()?).into();
$crate::callback::convert(py, result)
})
}
Some(wrap::<$class>)
}};
@ -130,7 +116,7 @@ macro_rules! py_binary_num_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_binary_reverse_num_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
($trait:ident, $class:ident :: $f:ident) => {{
unsafe extern "C" fn wrap<T>(
lhs: *mut ffi::PyObject,
rhs: *mut ffi::PyObject,
@ -140,11 +126,16 @@ macro_rules! py_binary_reverse_num_func {
{
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
// Swap lhs <-> rhs
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(rhs);
let arg = py.from_borrowed_ptr::<$crate::PyAny>(lhs);
call_ref_with_converter!(slf, $conv, py, $f, arg)
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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(),
)
})
}
Some(wrap::<$class>)
}};
@ -165,17 +156,14 @@ macro_rules! py_binary_self_func {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf_ = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg);
let result = call_mut!(slf_, $f, arg);
match result {
Ok(_) => {
ffi::Py_INCREF(slf);
slf
}
Err(e) => e.restore_and_null(py),
}
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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)?;
ffi::Py_INCREF(slf);
Ok(slf)
})
}
Some(wrap::<$class>)
}};
@ -185,15 +173,10 @@ macro_rules! py_binary_self_func {
#[doc(hidden)]
macro_rules! py_ssizearg_func {
// Use call_ref! by default
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_ssizearg_func!(
$trait,
$class::$f,
$conv,
call_ref_with_converter
)
($trait:ident, $class:ident :: $f:ident) => {
py_ssizearg_func!($trait, $class::$f, call_ref)
};
($trait:ident, $class:ident :: $f:ident, $conv:expr, $call:ident) => {{
($trait:ident, $class:ident :: $f:ident, $call:ident) => {{
unsafe extern "C" fn wrap<T>(
slf: *mut ffi::PyObject,
arg: $crate::ffi::Py_ssize_t,
@ -202,9 +185,11 @@ macro_rules! py_ssizearg_func {
T: for<'p> $trait<'p>,
{
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
$call!(slf, $conv, py, $f ;arg.into())
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
$crate::callback::convert(py, $call!(slf, $f; arg.into()))
})
}
Some(wrap::<$class>)
}};
@ -213,10 +198,7 @@ macro_rules! py_ssizearg_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_ternary_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_ternary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject);
};
($trait:ident, $class:ident :: $f:ident, $conv:expr, $return_type:ty) => {{
($trait:ident, $class:ident :: $f:ident, $return_type:ty) => {{
unsafe extern "C" fn wrap<T>(
slf: *mut $crate::ffi::PyObject,
arg1: *mut $crate::ffi::PyObject,
@ -228,22 +210,31 @@ macro_rules! py_ternary_func {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyAny>(arg2);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg1 = py
.from_borrowed_ptr::<$crate::types::PyAny>(arg1)
.extract()?;
let arg2 = py
.from_borrowed_ptr::<$crate::types::PyAny>(arg2)
.extract()?;
call_ref_with_converter!(slf, $conv, py, $f, arg1, arg2)
$crate::callback::convert(py, slf.try_borrow()?.$f(arg1, arg2).into())
})
}
Some(wrap::<T>)
}};
($trait:ident, $class:ident :: $f:ident) => {
py_ternary_func!($trait, $class::$f, *mut $crate::ffi::PyObject);
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_ternary_num_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
($trait:ident, $class:ident :: $f:ident) => {{
unsafe extern "C" fn wrap<T>(
arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject,
@ -255,22 +246,21 @@ macro_rules! py_ternary_num_func {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyAny>(arg2);
let arg3 = py.from_borrowed_ptr::<$crate::PyAny>(arg3);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let arg1 = py
.from_borrowed_ptr::<$crate::types::PyAny>(arg1)
.extract()?;
let arg2 = py
.from_borrowed_ptr::<$crate::types::PyAny>(arg2)
.extract()?;
let arg3 = py
.from_borrowed_ptr::<$crate::types::PyAny>(arg3)
.extract()?;
let result = match arg1.extract() {
Ok(arg1) => match arg2.extract() {
Ok(arg2) => match arg3.extract() {
Ok(arg3) => $class::$f(arg1, arg2, arg3).into(),
Err(e) => Err(e.into()),
},
Err(e) => Err(e.into()),
},
Err(e) => Err(e.into()),
};
$crate::callback::cb_convert($conv, py, result)
let result = $class::$f(arg1, arg2, arg3).into();
$crate::callback::convert(py, result)
})
}
Some(wrap::<T>)
@ -280,7 +270,7 @@ macro_rules! py_ternary_num_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_ternary_reverse_num_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
($trait:ident, $class:ident :: $f:ident) => {{
unsafe extern "C" fn wrap<T>(
arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject,
@ -291,12 +281,16 @@ macro_rules! py_ternary_reverse_num_func {
{
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
// Swap lhs <-> rhs
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(arg2);
let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyAny>(arg3);
call_ref_with_converter!(slf, $conv, py, $f, arg1, arg2)
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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)
})
}
Some(wrap::<$class>)
}};
@ -319,17 +313,14 @@ macro_rules! py_dummy_ternary_self_func {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf_ = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
let result = call_mut!(slf_, $f, arg);
match result {
Ok(_) => {
ffi::Py_INCREF(slf);
slf
}
Err(e) => e.restore_and_null(py),
}
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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)?;
ffi::Py_INCREF(slf);
Ok(slf)
})
}
Some(wrap::<$class>)
}};
@ -348,25 +339,23 @@ macro_rules! py_func_set {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<$generic>>(slf);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<$generic>>(slf);
let result = if value.is_null() {
Err($crate::PyErr::new::<exceptions::NotImplementedError, _>(
format!(
"Subscript deletion not supported by {:?}",
stringify!($generic)
),
))
} else {
let name = py.from_borrowed_ptr::<$crate::PyAny>(name);
let value = py.from_borrowed_ptr::<$crate::PyAny>(value);
call_mut!(slf, $fn_set, name, value)
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(py),
}
if value.is_null() {
Err($crate::PyErr::new::<exceptions::NotImplementedError, _>(
format!(
"Subscript deletion not supported by {:?}",
stringify!($generic)
),
))
} 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))
}
})
}
Some(wrap::<$generic>)
@ -386,22 +375,21 @@ macro_rules! py_func_del {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(py);
let result = if value.is_null() {
let slf = py.from_borrowed_ptr::<$crate::PyCell<U>>(slf);
let name = py.from_borrowed_ptr::<$crate::PyAny>(name);
call_mut!(slf, $fn_del, name)
} else {
Err(PyErr::new::<exceptions::NotImplementedError, _>(
"Subscript assignment not supported",
))
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(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())
} else {
Err(PyErr::new::<exceptions::NotImplementedError, _>(
"Subscript assignment not supported",
))
}
})
}
Some(wrap::<$generic>)
@ -421,71 +409,43 @@ macro_rules! py_func_set_del {
use $crate::ObjectProtocol;
let py = $crate::Python::assume_gil_acquired();
let _pool = $crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<$crate::PyCell<$generic>>(slf);
let name = py.from_borrowed_ptr::<$crate::PyAny>(name);
$crate::run_callback(py, || {
let _pool = $crate::GILPool::new(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() {
call_mut!(slf, $fn_del, name)
} else {
let value = py.from_borrowed_ptr::<$crate::PyAny>(value);
call_mut!(slf, $fn_set, name, value)
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(py),
}
let result = 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>)
}};
}
macro_rules! _call_impl {
($slf: ident, $fn: ident $(; $args: expr)*) => { $slf.$fn($($args,)*).into() };
($slf: ident, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
match $raw_arg.extract() {
Ok(arg) => _call_impl!($slf, $fn $(,$raw_args)* $(;$args)* ;arg),
Err(e) => Err(e.into()),
}
($slf: expr, $fn: ident $(; $args: expr)*) => {
$slf.$fn($($args,)*).into()
};
($slf: expr, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
_call_impl!($slf, $fn $(,$raw_args)* $(;$args)* ;$raw_arg.extract()?)
};
}
/// Call `slf.try_borrow()?.$fn(...)`
macro_rules! call_ref {
($slf: expr, $fn: ident $(,$raw_args: expr)* $(; $args: expr)*) => {
match $slf.try_borrow() {
Ok(slf) => _call_impl!(slf, $fn $(,$raw_args)* $(;$args)*),
Err(e) => Err(e.into()),
}
};
}
/// Call `slf.try_borrow()?.$fn(...)` and returns the result using the given CallbackConverter
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)
}
_call_impl!($slf.try_borrow()?, $fn $(,$raw_args)* $(;$args)*)
};
}
/// Call `slf.try_borrow_mut()?.$fn(...)`
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()),
}
};
}
/// Call `slf.try_borrow_mut()?.$fn(...)` and returns the result using the given CallbackConverter
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)
}
_call_impl!($slf.try_borrow_mut()?, $fn $(,$raw_args)* $(;$args)*)
};
}

View File

@ -3,10 +3,9 @@
//! Python Mapping Interface
//! Trait and support implementation for implementing mapping support
use crate::callback::{LenResultConverter, PyObjectCallbackConverter};
use crate::class::methods::PyMethodDef;
use crate::err::{PyErr, PyResult};
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyClass, PyObject, Python};
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyClass, PyObject};
/// Mapping interface
#[allow(unused_variables)]
@ -141,7 +140,7 @@ where
{
#[inline]
fn mp_length() -> Option<ffi::lenfunc> {
py_len_func!(PyMappingLenProtocol, T::__len__, LenResultConverter)
py_len_func!(PyMappingLenProtocol, T::__len__)
}
}
@ -164,11 +163,7 @@ where
{
#[inline]
fn mp_subscript() -> Option<ffi::binaryfunc> {
py_binary_func!(
PyMappingGetItemProtocol,
T::__getitem__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_func!(PyMappingGetItemProtocol, T::__getitem__)
}
}

View File

@ -3,7 +3,6 @@
//! Python Number Interface
//! Trait and support implementation for implementing number protocol
use crate::callback::PyObjectCallbackConverter;
use crate::class::basic::PyObjectProtocolImpl;
use crate::class::methods::PyMethodDef;
use crate::err::PyResult;
@ -761,11 +760,7 @@ where
T: for<'p> PyNumberAddProtocol<'p>,
{
fn nb_add() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberAddProtocol,
T::__add__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberAddProtocol, T::__add__)
}
}
@ -787,11 +782,7 @@ where
T: for<'p> PyNumberSubProtocol<'p>,
{
fn nb_subtract() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberSubProtocol,
T::__sub__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberSubProtocol, T::__sub__)
}
}
@ -813,11 +804,7 @@ where
T: for<'p> PyNumberMulProtocol<'p>,
{
fn nb_multiply() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberMulProtocol,
T::__mul__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberMulProtocol, T::__mul__)
}
}
@ -839,11 +826,7 @@ where
T: for<'p> PyNumberMatmulProtocol<'p>,
{
fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberMatmulProtocol,
T::__matmul__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberMatmulProtocol, T::__matmul__)
}
}
@ -865,11 +848,7 @@ where
T: for<'p> PyNumberTruedivProtocol<'p>,
{
fn nb_true_divide() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberTruedivProtocol,
T::__truediv__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberTruedivProtocol, T::__truediv__)
}
}
@ -891,11 +870,7 @@ where
T: for<'p> PyNumberFloordivProtocol<'p>,
{
fn nb_floor_divide() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberFloordivProtocol,
T::__floordiv__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberFloordivProtocol, T::__floordiv__)
}
}
@ -917,11 +892,7 @@ where
T: for<'p> PyNumberModProtocol<'p>,
{
fn nb_remainder() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberModProtocol,
T::__mod__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberModProtocol, T::__mod__)
}
}
@ -943,11 +914,7 @@ where
T: for<'p> PyNumberDivmodProtocol<'p>,
{
fn nb_divmod() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberDivmodProtocol,
T::__divmod__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberDivmodProtocol, T::__divmod__)
}
}
@ -969,11 +936,7 @@ where
T: for<'p> PyNumberPowProtocol<'p>,
{
fn nb_power() -> Option<ffi::ternaryfunc> {
py_ternary_num_func!(
PyNumberPowProtocol,
T::__pow__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_ternary_num_func!(PyNumberPowProtocol, T::__pow__)
}
}
@ -995,11 +958,7 @@ where
T: for<'p> PyNumberLShiftProtocol<'p>,
{
fn nb_lshift() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberLShiftProtocol,
T::__lshift__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberLShiftProtocol, T::__lshift__)
}
}
@ -1021,11 +980,7 @@ where
T: for<'p> PyNumberRShiftProtocol<'p>,
{
fn nb_rshift() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberRShiftProtocol,
T::__rshift__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberRShiftProtocol, T::__rshift__)
}
}
@ -1047,11 +1002,7 @@ where
T: for<'p> PyNumberAndProtocol<'p>,
{
fn nb_and() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberAndProtocol,
T::__and__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberAndProtocol, T::__and__)
}
}
@ -1073,11 +1024,7 @@ where
T: for<'p> PyNumberXorProtocol<'p>,
{
fn nb_xor() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberXorProtocol,
T::__xor__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberXorProtocol, T::__xor__)
}
}
@ -1099,11 +1046,7 @@ where
T: for<'p> PyNumberOrProtocol<'p>,
{
fn nb_or() -> Option<ffi::binaryfunc> {
py_binary_num_func!(
PyNumberOrProtocol,
T::__or__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_num_func!(PyNumberOrProtocol, T::__or__)
}
}
@ -1426,11 +1369,7 @@ where
T: for<'p> PyNumberRAddProtocol<'p>,
{
fn nb_add_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRAddProtocol,
T::__radd__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRAddProtocol, T::__radd__)
}
}
@ -1466,11 +1405,7 @@ where
T: for<'p> PyNumberRSubProtocol<'p>,
{
fn nb_sub_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRSubProtocol,
T::__rsub__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRSubProtocol, T::__rsub__)
}
}
@ -1506,11 +1441,7 @@ where
T: for<'p> PyNumberRMulProtocol<'p>,
{
fn nb_mul_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRMulProtocol,
T::__rmul__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRMulProtocol, T::__rmul__)
}
}
@ -1546,11 +1477,7 @@ where
T: for<'p> PyNumberRMatmulProtocol<'p>,
{
fn nb_matmul_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRMatmulProtocol,
T::__rmatmul__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRMatmulProtocol, T::__rmatmul__)
}
}
@ -1586,11 +1513,7 @@ where
T: for<'p> PyNumberRTruedivProtocol<'p>,
{
fn nb_truediv_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRTruedivProtocol,
T::__rtruediv__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRTruedivProtocol, T::__rtruediv__)
}
}
@ -1626,11 +1549,7 @@ where
T: for<'p> PyNumberRFloordivProtocol<'p>,
{
fn nb_floordiv_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRFloordivProtocol,
T::__rfloordiv__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRFloordivProtocol, T::__rfloordiv__)
}
}
@ -1666,11 +1585,7 @@ where
T: for<'p> PyNumberRModProtocol<'p>,
{
fn nb_mod_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRModProtocol,
T::__rmod__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRModProtocol, T::__rmod__)
}
}
@ -1706,11 +1621,7 @@ where
T: for<'p> PyNumberRDivmodProtocol<'p>,
{
fn nb_divmod_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRDivmodProtocol,
T::__rdivmod__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRDivmodProtocol, T::__rdivmod__)
}
}
@ -1746,11 +1657,7 @@ where
T: for<'p> PyNumberRPowProtocol<'p>,
{
fn nb_pow_fallback() -> Option<ffi::ternaryfunc> {
py_ternary_reverse_num_func!(
PyNumberRPowProtocol,
T::__rpow__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_ternary_reverse_num_func!(PyNumberRPowProtocol, T::__rpow__)
}
}
@ -1786,11 +1693,7 @@ where
T: for<'p> PyNumberRLShiftProtocol<'p>,
{
fn nb_lshift_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRLShiftProtocol,
T::__rlshift__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRLShiftProtocol, T::__rlshift__)
}
}
@ -1826,11 +1729,7 @@ where
T: for<'p> PyNumberRRShiftProtocol<'p>,
{
fn nb_rshift_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRRShiftProtocol,
T::__rrshift__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRRShiftProtocol, T::__rrshift__)
}
}
@ -1866,11 +1765,7 @@ where
T: for<'p> PyNumberRAndProtocol<'p>,
{
fn nb_and_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRAndProtocol,
T::__rand__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRAndProtocol, T::__rand__)
}
}
@ -1906,11 +1801,7 @@ where
T: for<'p> PyNumberRXorProtocol<'p>,
{
fn nb_xor_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberRXorProtocol,
T::__rxor__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberRXorProtocol, T::__rxor__)
}
}
@ -1946,11 +1837,7 @@ where
T: for<'p> PyNumberROrProtocol<'p>,
{
fn nb_or_fallback() -> Option<ffi::binaryfunc> {
py_binary_reverse_num_func!(
PyNumberROrProtocol,
T::__ror__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_reverse_num_func!(PyNumberROrProtocol, T::__ror__)
}
}
@ -1973,11 +1860,7 @@ where
{
#[inline]
fn nb_negative() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberNegProtocol,
T::__neg__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberNegProtocol, T::__neg__)
}
}
@ -1999,11 +1882,7 @@ where
T: for<'p> PyNumberPosProtocol<'p>,
{
fn nb_positive() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberPosProtocol,
T::__pos__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberPosProtocol, T::__pos__)
}
}
@ -2025,11 +1904,7 @@ where
T: for<'p> PyNumberAbsProtocol<'p>,
{
fn nb_absolute() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberAbsProtocol,
T::__abs__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberAbsProtocol, T::__abs__)
}
}
@ -2051,11 +1926,7 @@ where
T: for<'p> PyNumberInvertProtocol<'p>,
{
fn nb_invert() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberInvertProtocol,
T::__invert__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberInvertProtocol, T::__invert__)
}
}
@ -2077,11 +1948,7 @@ where
T: for<'p> PyNumberIntProtocol<'p>,
{
fn nb_int() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberIntProtocol,
T::__int__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberIntProtocol, T::__int__)
}
}
@ -2103,11 +1970,7 @@ where
T: for<'p> PyNumberFloatProtocol<'p>,
{
fn nb_float() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberFloatProtocol,
T::__float__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberFloatProtocol, T::__float__)
}
}
@ -2129,11 +1992,7 @@ where
T: for<'p> PyNumberIndexProtocol<'p>,
{
fn nb_index() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyNumberIndexProtocol,
T::__index__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyNumberIndexProtocol, T::__index__)
}
}

View File

@ -8,7 +8,6 @@
//! [PEP-0492](https://www.python.org/dev/peps/pep-0492/)
//!
use crate::callback::PyObjectCallbackConverter;
use crate::class::methods::PyMethodDef;
use crate::err::PyResult;
use crate::{ffi, PyClass, PyObject};
@ -150,11 +149,7 @@ where
{
#[inline]
fn am_await() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyAsyncAwaitProtocol,
T::__await__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyAsyncAwaitProtocol, T::__await__)
}
}
@ -177,11 +172,7 @@ where
{
#[inline]
fn am_aiter() -> Option<ffi::unaryfunc> {
py_unary_func!(
PyAsyncAiterProtocol,
T::__aiter__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_unary_func!(PyAsyncAiterProtocol, T::__aiter__)
}
}
@ -200,30 +191,22 @@ where
mod anext {
use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
use crate::callback::CallbackConverter;
use crate::callback::IntoPyCallbackOutput;
use crate::err::PyResult;
use crate::IntoPyPointer;
use crate::Python;
use crate::{ffi, IntoPy, PyObject};
use std::marker::PhantomData;
use std::ptr;
struct IterANextResultConverter<T>(PhantomData<T>);
struct IterANextOutput<T>(Option<T>);
impl<T> CallbackConverter for IterANextResultConverter<T>
impl<T> IntoPyCallbackOutput<*mut ffi::PyObject> for IterANextOutput<T>
where
T: IntoPy<PyObject>,
{
type Source = Option<T>;
type Result = *mut ffi::PyObject;
const ERR_VALUE: Self::Result = ptr::null_mut();
fn convert(val: Self::Source, py: Python) -> Self::Result {
match val {
Some(val) => val.into_py(py).into_ptr(),
None => unsafe {
ffi::PyErr_SetNone(ffi::PyExc_StopAsyncIteration);
ptr::null_mut()
},
fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> {
match self.0 {
Some(val) => Ok(val.into_py(py).into_ptr()),
None => Err(crate::exceptions::StopAsyncIteration::py_err(())),
}
}
}
@ -237,9 +220,9 @@ mod anext {
py_unary_func!(
PyAsyncAnextProtocol,
T::__anext__,
IterANextResultConverter::<T::Success>(std::marker::PhantomData),
call_mut,
*mut crate::ffi::PyObject,
call_mut_with_converter
IterANextOutput
)
}
}

View File

@ -3,10 +3,11 @@
//! Python Sequence Interface
//! Trait and support implementation for implementing sequence
use crate::callback::{BoolCallbackConverter, LenResultConverter, PyObjectCallbackConverter};
use crate::conversion::{FromPyObject, IntoPy};
use crate::err::{PyErr, PyResult};
use crate::gil::GILPool;
use crate::objectprotocol::ObjectProtocol;
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyAny, PyClass, PyObject, Python};
use crate::{callback, exceptions, ffi, run_callback, PyAny, PyCell, PyClass, PyObject, Python};
use std::os::raw::c_int;
/// Sequence interface
@ -176,7 +177,7 @@ where
T: for<'p> PySequenceLenProtocol<'p>,
{
fn sq_length() -> Option<ffi::lenfunc> {
py_len_func!(PySequenceLenProtocol, T::__len__, LenResultConverter)
py_len_func!(PySequenceLenProtocol, T::__len__)
}
}
@ -198,11 +199,7 @@ where
T: for<'p> PySequenceGetItemProtocol<'p>,
{
fn sq_item() -> Option<ffi::ssizeargfunc> {
py_ssizearg_func!(
PySequenceGetItemProtocol,
T::__getitem__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_ssizearg_func!(PySequenceGetItemProtocol, T::__getitem__)
}
}
@ -260,31 +257,23 @@ mod sq_ass_item_impl {
T: for<'p> PySequenceSetItemProtocol<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
run_callback(py, || {
let _pool = GILPool::new(py);
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
if value.is_null() {
return PyErr::new::<exceptions::NotImplementedError, _>(format!(
"Item deletion is not supported by {:?}",
stringify!(T)
))
.restore_and_minus1(py);
}
let result = match slf.try_borrow_mut() {
Ok(mut slf) => {
let value = py.from_borrowed_ptr::<PyAny>(value);
match value.extract() {
Ok(value) => slf.__setitem__(key.into(), value).into(),
Err(e) => e.into(),
}
if value.is_null() {
return Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
"Item deletion is not supported by {:?}",
stringify!(T)
)));
}
Err(e) => Err(PyErr::from(e)),
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(py),
}
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)
})
}
Some(wrap::<T>)
}
@ -317,22 +306,21 @@ mod sq_ass_item_impl {
T: for<'p> PySequenceDelItemProtocol<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
run_callback(py, || {
let _pool = GILPool::new(py);
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
let result = 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)
)))
};
let result = 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)
)))
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(py),
}
callback::convert(py, result)
})
}
Some(wrap::<T>)
}
@ -365,25 +353,20 @@ mod sq_ass_item_impl {
T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
{
let py = Python::assume_gil_acquired();
let _pool = crate::GILPool::new(py);
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
run_callback(py, || {
let _pool = GILPool::new(py);
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
let result = if value.is_null() {
call_mut!(slf, __delitem__; key.into())
} else {
let value = py.from_borrowed_ptr::<PyAny>(value);
match slf.try_borrow_mut() {
Ok(mut slf_) => match value.extract() {
Ok(value) => slf_.__setitem__(key.into(), value).into(),
Err(e) => Err(e),
},
Err(e) => Err(e.into()),
}
};
match result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(py),
}
let result = 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>)
}
@ -408,12 +391,7 @@ where
T: for<'p> PySequenceContainsProtocol<'p>,
{
fn sq_contains() -> Option<ffi::objobjproc> {
py_binary_func!(
PySequenceContainsProtocol,
T::__contains__,
BoolCallbackConverter,
c_int
)
py_binary_func!(PySequenceContainsProtocol, T::__contains__, c_int)
}
}
@ -435,11 +413,7 @@ where
T: for<'p> PySequenceConcatProtocol<'p>,
{
fn sq_concat() -> Option<ffi::binaryfunc> {
py_binary_func!(
PySequenceConcatProtocol,
T::__concat__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_binary_func!(PySequenceConcatProtocol, T::__concat__)
}
}
@ -461,11 +435,7 @@ where
T: for<'p> PySequenceRepeatProtocol<'p>,
{
fn sq_repeat() -> Option<ffi::ssizeargfunc> {
py_ssizearg_func!(
PySequenceRepeatProtocol,
T::__repeat__,
PyObjectCallbackConverter::<T::Success>(std::marker::PhantomData)
)
py_ssizearg_func!(PySequenceRepeatProtocol, T::__repeat__)
}
}
@ -490,9 +460,8 @@ where
py_binary_func!(
PySequenceInplaceConcatProtocol,
T::__inplace_concat__,
PyObjectCallbackConverter::<T>(std::marker::PhantomData),
*mut crate::ffi::PyObject,
call_mut_with_converter
*mut ffi::PyObject,
call_mut
)
}
}
@ -518,8 +487,7 @@ where
py_ssizearg_func!(
PySequenceInplaceRepeatProtocol,
T::__inplace_repeat__,
PyObjectCallbackConverter::<T>(std::marker::PhantomData),
call_mut_with_converter
call_mut
)
}
}

View File

@ -1,15 +1,12 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::instance::Py;
use crate::object::PyObject;
use crate::type_object::PyTypeObject;
use crate::types::{PyAny, PyType};
use crate::AsPyPointer;
use crate::IntoPyPointer;
use crate::Python;
use crate::{exceptions, IntoPy};
use crate::{ffi, FromPy};
use crate::{ToBorrowedObject, ToPyObject};
use crate::types::PyType;
use crate::{exceptions, ffi};
use crate::{
AsPyPointer, FromPy, IntoPy, IntoPyPointer, Py, PyAny, PyObject, Python, ToBorrowedObject,
ToPyObject,
};
use libc::c_int;
use std::ffi::CString;
use std::io;

View File

@ -133,6 +133,7 @@
//! }
//! ```
pub use crate::callback::run_callback;
pub use crate::class::*;
pub use crate::conversion::{
AsPyPointer, FromPy, FromPyObject, FromPyPointer, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto,

View File

@ -9,8 +9,7 @@ use crate::instance::AsPyRef;
use crate::object::PyObject;
use crate::type_object::{PyDowncastImpl, PyTypeInfo, PyTypeObject};
use crate::types::{PyAny, PyDict, PyModule, PyType};
use crate::AsPyPointer;
use crate::{FromPyPointer, IntoPyPointer, PyTryFrom};
use crate::{AsPyPointer, FromPyPointer, IntoPyPointer, PyTryFrom};
use std::ffi::CString;
use std::marker::PhantomData;
use std::os::raw::c_int;