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 let is_mut = self
.self_ .self_
.expect("impl_borrow_self is called for non-self fn"); .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 /// 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), "()"); const _LOCATION: &'static str = concat!(stringify!(#name), "()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); let _pool = pyo3::GILPool::new(_py);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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 slf = quote! {
let _cell = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf); let _cell = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
let _slf: #self_ty = match std::convert::TryFrom::try_from(_cell) { let _slf: #self_ty = std::convert::TryFrom::try_from(_cell)?;
Ok(_slf) => _slf,
Err(e) => return pyo3::PyErr::from(e).restore_and_null(_py),
};
}; };
impl_wrap_common(cls, spec, noargs, slf, body) impl_wrap_common(cls, spec, noargs, slf, body)
} }
@ -109,13 +106,11 @@ fn impl_wrap_common(
const _LOCATION: &'static str = concat!( const _LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#python_name), "()"); stringify!(#cls), ".", stringify!(#python_name), "()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
#slf let _pool = pyo3::GILPool::new(_py);
let _result = { #slf
pyo3::derive_utils::IntoPyResult::into_py_result(#body) pyo3::callback::convert(_py, #body)
}; })
pyo3::callback::cb_obj_convert(_py, _result)
} }
} }
} else { } else {
@ -130,14 +125,16 @@ fn impl_wrap_common(
const _LOCATION: &'static str = concat!( const _LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#python_name), "()"); stringify!(#cls), ".", stringify!(#python_name), "()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
#slf let _pool = pyo3::GILPool::new(_py);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); #slf
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf); let _pool = pyo3::GILPool::new(_py);
#borrow_self let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); #borrow_self
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); let _pool = pyo3::GILPool::new(_py);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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)) { let cell = pyo3::PyClassInitializer::from(_result?).create_cell(_py)?;
Ok(slf) => slf as _, Ok(cell as *mut pyo3::ffi::PyObject)
Err(e) => e.restore_and_null(_py), })
}
} }
} }
} }
@ -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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _cls = pyo3::types::PyType::from_type_ptr(_py, _cls as *mut pyo3::ffi::PyTypeObject); let _pool = pyo3::GILPool::new(_py);
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); let _cls = pyo3::types::PyType::from_type_ptr(_py, _cls as *mut pyo3::ffi::PyTypeObject);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args); let _pool = pyo3::GILPool::new(_py);
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); 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)?), 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! { Ok(quote! {
unsafe extern "C" fn __wrap( unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> *mut pyo3::ffi::PyObject _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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf); let _pool = pyo3::GILPool::new(_py);
#borrow_self let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
#borrow_self
let result = pyo3::derive_utils::IntoPyResult::into_py_result(#getter_impl); pyo3::callback::convert(_py, #getter_impl)
})
match result {
Ok(val) => pyo3::IntoPyPointer::into_ptr(pyo3::IntoPy::<PyObject>::into_py(val, _py)),
Err(e) => e.restore_and_null(_py),
}
} }
}) })
} }
@ -344,9 +343,9 @@ fn impl_call_setter(spec: &FnSpec) -> syn::Result<TokenStream> {
let name = &spec.name; let name = &spec.name;
let fncall = if py_arg.is_some() { 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 { } 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) Ok(fncall)
@ -360,12 +359,12 @@ pub(crate) fn impl_wrap_setter(
let (python_name, setter_impl) = match property_type { let (python_name, setter_impl) = match property_type {
PropertyType::Descriptor(field) => { PropertyType::Descriptor(field) => {
let name = field.ident.as_ref().unwrap(); 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)?), 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! { Ok(quote! {
#[allow(unused_mut)] #[allow(unused_mut)]
unsafe extern "C" fn __wrap( 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),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()");
let _py = pyo3::Python::assume_gil_acquired(); let _py = pyo3::Python::assume_gil_acquired();
let _pool = pyo3::GILPool::new(_py); pyo3::run_callback(_py, || {
let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf); let _pool = pyo3::GILPool::new(_py);
#borrow_self let _slf = _py.from_borrowed_ptr::<pyo3::PyCell<#cls>>(_slf);
let _value = _py.from_borrowed_ptr(_value); #borrow_self
let _value = _py.from_borrowed_ptr::<pyo3::types::PyAny>(_value);
let _result = match pyo3::FromPyObject::extract(_value) { let _val = pyo3::FromPyObject::extract(_value)?;
Ok(_val) => { pyo3::callback::convert(_py, {#setter_impl})
#setter_impl })
}
Err(e) => Err(e)
};
match _result {
Ok(_) => 0,
Err(e) => e.restore_and_minus1(_py),
}
} }
}) })
} }
@ -462,22 +454,19 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre
let mut _args = _args; let mut _args = _args;
let mut _kwargs = _kwargs; let mut _kwargs = _kwargs;
// Workaround to use the question mark operator without rewriting everything let (_args, _kwargs) = pyo3::derive_utils::parse_fn_args(
let _result = (|| { Some(_LOCATION),
let (_args, _kwargs) = pyo3::derive_utils::parse_fn_args( PARAMS,
Some(_LOCATION), _args,
PARAMS, _kwargs,
_args, #accept_args,
_kwargs, #accept_kwargs,
#accept_args, &mut output
#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 quote::quote;
use std::fmt::Display; use std::fmt::Display;
pub(crate) fn borrow_self(is_mut: bool, return_null: bool) -> TokenStream { pub(crate) fn borrow_self(is_mut: bool) -> TokenStream {
let ret = if return_null {
quote! { restore_and_null }
} else {
quote! { restore_and_minus1 }
};
if is_mut { if is_mut {
quote! { quote! {
let mut _slf = match _slf.try_borrow_mut() { let mut _slf = _slf.try_borrow_mut()?;
Ok(ref_) => ref_,
Err(e) => return pyo3::PyErr::from(e).#ret(_py),
};
} }
} else { } else {
quote! { quote! {
let _slf = match _slf.try_borrow() { let _slf = _slf.try_borrow()?;
Ok(ref_) => ref_,
Err(e) => return pyo3::PyErr::from(e).#ret(_py),
};
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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