diff --git a/Cargo.toml b/Cargo.toml index 06798679..69d7cfcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ exclude = [ build = "build.rs" [dependencies] +log = "0.3" libc = "0.2" num-traits = "0.1" pyo3cls = { path = "pyo3cls" } diff --git a/pyo3cls/src/py_class.rs b/pyo3cls/src/py_class.rs index 1268755c..4f061320 100644 --- a/pyo3cls/src/py_class.rs +++ b/pyo3cls/src/py_class.rs @@ -49,25 +49,27 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option) -> impl std::fmt::Debug for #cls { fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + let py = _pyo3::PyObjectWithToken::token(self); let ptr = <#cls as _pyo3::python::ToPyPointer>::as_ptr(self); let repr = unsafe { _pyo3::PyString::downcast_from_ptr( - self.token(), _pyo3::ffi::PyObject_Repr(ptr)) + py, _pyo3::ffi::PyObject_Repr(ptr)) .map_err(|_| std::fmt::Error)? }; - f.write_str(&repr.to_string_lossy(self.token())) + f.write_str(&repr.to_string_lossy(py)) } } impl std::fmt::Display for #cls { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + let py = _pyo3::PyObjectWithToken::token(self); let ptr = <#cls as _pyo3::python::ToPyPointer>::as_ptr(self); let str_obj = unsafe { _pyo3::PyString::downcast_from_ptr( - self.token(), _pyo3::ffi::PyObject_Str(ptr)) + py, _pyo3::ffi::PyObject_Str(ptr)) .map_err(|_| std::fmt::Error)? }; - f.write_str(&str_obj.to_string_lossy(self.token())) + f.write_str(&str_obj.to_string_lossy(py)) } } }) @@ -122,7 +124,44 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option) -> } } } + impl _pyo3::python::PyMutDowncastFrom for #cls + { + fn downcast_mut_from<'a, 'p>(py: Python<'p>, ob: &'a mut _pyo3::PyObject) + -> Result<&'a mut #cls, _pyo3::PyDowncastError<'p>> + { + unsafe { + let checked = ffi::PyObject_TypeCheck( + ob.as_ptr(), <#cls as _pyo3::typeob::PyTypeInfo>::type_object()) != 0; + if checked { + let offset = <#cls as _pyo3::typeob::PyTypeInfo>::offset(); + let ptr = (ob.as_ptr() as *mut u8).offset(offset) as *mut #cls; + Ok(ptr.as_mut().unwrap()) + } else { + Err(_pyo3::PyDowncastError(py, None)) + } + } + } + } + impl _pyo3::ToPyObject for #cls + { + #[inline] + fn to_object<'p>(&self, py: _pyo3::Python<'p>) -> _pyo3::PyObject { + _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) + } + + #[inline] + fn with_borrowed_ptr(&self, _py: _pyo3::Python, f: F) -> R + where F: FnOnce(*mut ffi::PyObject) -> R + { + f(self.as_ptr()) + } + } + impl std::convert::AsRef for #cls { + fn as_ref(&self) -> &_pyo3::PyObject { + unsafe{std::mem::transmute(self.as_ptr())} + } + } impl _pyo3::python::ToPyPointer for #cls { #[inline] fn as_ptr(&self) -> *mut ffi::PyObject { diff --git a/pyo3cls/src/py_method.rs b/pyo3cls/src/py_method.rs index a347f2de..e6ab7dac 100644 --- a/pyo3cls/src/py_method.rs +++ b/pyo3cls/src/py_method.rs @@ -260,7 +260,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens { if spec.is_args(&name) { quote! { - match <#ty as _pyo3::FromPyObject>::extract(py, &args) + match <#ty as _pyo3::FromPyObject>::extract(py, &args.into()) { Ok(#name) => { #body @@ -310,7 +310,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens { quote! { match match _iter.next().unwrap().as_ref() { Some(obj) => { - if obj.is_none() { + if obj.is_none(py) { Ok(#default) } else { match obj.extract(py) { diff --git a/pyo3cls/src/py_ptr.rs b/pyo3cls/src/py_ptr.rs index 998e67dc..a5edb0a6 100644 --- a/pyo3cls/src/py_ptr.rs +++ b/pyo3cls/src/py_ptr.rs @@ -19,10 +19,10 @@ pub fn build_ptr(cls: syn::Ident, ast: &mut syn::DeriveInput) -> Tokens { unsafe impl Send for #ptr {} unsafe impl Sync for #ptr {} - impl _pyo3::Park<#cls> for #cls { - type ParkTarget = #ptr; + impl _pyo3::ToInstancePtr<#cls> for #cls { + type Target = #ptr; - fn park(&self) -> #ptr { + fn to_inst_ptr(&self) -> #ptr { let token = _pyo3::PyObjectWithToken::token(self); let ptr = self.as_ptr(); @@ -37,7 +37,7 @@ pub fn build_ptr(cls: syn::Ident, ast: &mut syn::DeriveInput) -> Tokens { } } - impl _pyo3::PythonPtr<#cls> for #ptr { + impl _pyo3::InstancePtr<#cls> for #ptr { #[inline] fn as_ref(&self, _py: Python) -> &#cls { @@ -64,7 +64,6 @@ pub fn build_ptr(cls: syn::Ident, ast: &mut syn::DeriveInput) -> Tokens { &self.0 } } - impl _pyo3::PyClone for #ptr { fn clone_ref(&self, _py: _pyo3::Python) -> #ptr { #ptr(unsafe{ _pyo3::PyPtr::from_borrowed_ptr(self.as_ptr()) }) @@ -88,6 +87,39 @@ pub fn build_ptr(cls: syn::Ident, ast: &mut syn::DeriveInput) -> Tokens { self.0.into_ptr() } } + impl _pyo3::PyDowncastInto for #ptr + { + fn downcast_into<'p, I>(py: _pyo3::Python<'p>, ob: I) + -> Result> + where I: _pyo3::IntoPyPointer + { + <#ptr as _pyo3::PyDowncastInto>::downcast_from_ptr(py, ob.into_ptr()) + } + + fn downcast_from_ptr<'p>(py: _pyo3::Python<'p>, ptr: *mut _pyo3::ffi::PyObject) + -> Result<#ptr, _pyo3::PyDowncastError<'p>> + { + unsafe{ + let checked = ffi::PyObject_TypeCheck( + ptr, <#cls as _pyo3::typeob::PyTypeInfo>::type_object()) != 0; + + if checked { + Ok(#ptr(PyPtr::from_owned_ptr(ptr))) + } else { + _pyo3::ffi::Py_DECREF(ptr); + Err(_pyo3::PyDowncastError(py, None)) + } + } + } + + fn unchecked_downcast_into<'p, I>(ob: I) -> Self where I: _pyo3::IntoPyPointer + { + unsafe{ + #ptr(_pyo3::PyPtr::from_owned_ptr(ob.into_ptr())) + } + } + } + impl std::convert::From<#ptr> for _pyo3::PyObject { fn from(ob: #ptr) -> Self { unsafe{std::mem::transmute(ob)} diff --git a/src/argparse.rs b/src/argparse.rs index 3ca72654..42f9228a 100644 --- a/src/argparse.rs +++ b/src/argparse.rs @@ -450,16 +450,16 @@ pub fn with_extracted_or_default<'p, P: ?Sized, R, F>( #[cfg(test)] mod test { - use python::{Python}; + use python::Python; use objects::PyTuple; - use conversion::{ToPyTuple}; + use conversion::IntoPyTuple; #[test] pub fn test_parse() { let gil_guard = Python::acquire_gil(); let py = gil_guard.python(); let mut called = false; - let tuple = ("abc", 42).to_py_tuple(py); + let tuple = ("abc", 42).into_tuple(py); py_argparse!(py, None, &tuple, None, (x: &str, y: i32) { assert_eq!(x, "abc"); assert_eq!(y, 42); @@ -474,7 +474,7 @@ mod test { let gil_guard = Python::acquire_gil(); let py = gil_guard.python(); let mut called = false; - let tuple = ("abc",).to_py_tuple(py); + let tuple = ("abc",).into_tuple(py); py_argparse!(py, None, &tuple, None, (x) { assert_eq!(*x, tuple.get_item(py, 0)); called = true; @@ -488,7 +488,7 @@ mod test { let gil_guard = Python::acquire_gil(); let py = gil_guard.python(); let mut called = false; - let tuple = (0, "foo").to_py_tuple(py); + let tuple = (0, "foo").into_tuple(py); py_argparse!(py, None, &tuple, None, (x: usize = 42, y: &str = "abc") { assert_eq!(x, 0); assert_eq!(y, "foo"); diff --git a/src/callback.rs b/src/callback.rs index 2d69a921..dda79a24 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -9,7 +9,7 @@ use objects::exc; use conversion::IntoPyObject; use ffi::{self, Py_hash_t}; use err::{PyErr, PyResult}; -use token::{Park, PythonPtr}; +use token::{InstancePtr, ToInstancePtr}; use typeob::PyTypeInfo; @@ -199,7 +199,7 @@ pub unsafe fn cb_unary(location: &str, slf: *mut ffi::PyObject, _c: C, f: F) -> C::R where F: for<'p> FnOnce(Python<'p>, &'p mut Slf) -> PyResult, F: panic::UnwindSafe, - Slf: PyTypeInfo + Park, + Slf: PyTypeInfo + ToInstancePtr, C: CallbackConverter { let guard = AbortOnDrop(location); @@ -234,7 +234,7 @@ pub unsafe fn cb_unary(location: &str, pub unsafe fn cb_unary_unit(location: &str, slf: *mut ffi::PyObject, f: F) -> c_int where F: for<'p> FnOnce(Python<'p>, &'p mut Slf) -> c_int, F: panic::UnwindSafe, - Slf: PyTypeInfo + Park, + Slf: PyTypeInfo + ToInstancePtr, { let guard = AbortOnDrop(location); let ret = panic::catch_unwind(|| { diff --git a/src/class/async.rs b/src/class/async.rs index 5eae3a83..6c545777 100644 --- a/src/class/async.rs +++ b/src/class/async.rs @@ -10,7 +10,7 @@ use ffi; use err::PyResult; use python::Python; use callback::PyObjectCallbackConverter; -use token::Park; +use token::ToInstancePtr; use typeob::PyTypeInfo; use class::methods::PyMethodDef; @@ -125,7 +125,7 @@ impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> } } -impl PyAsyncAwaitProtocolImpl for T where T: for<'p> PyAsyncAwaitProtocol<'p> + Park +impl PyAsyncAwaitProtocolImpl for T where T: for<'p> PyAsyncAwaitProtocol<'p> + ToInstancePtr { #[inline] fn am_await() -> Option { @@ -146,7 +146,7 @@ impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> } } -impl PyAsyncAiterProtocolImpl for T where T: for<'p> PyAsyncAiterProtocol<'p> + Park +impl PyAsyncAiterProtocolImpl for T where T: for<'p> PyAsyncAiterProtocol<'p> + ToInstancePtr { #[inline] fn am_aiter() -> Option { @@ -167,7 +167,7 @@ impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> } } -impl PyAsyncAnextProtocolImpl for T where T: for<'p> PyAsyncAnextProtocol<'p> + Park +impl PyAsyncAnextProtocolImpl for T where T: for<'p> PyAsyncAnextProtocol<'p> + ToInstancePtr { #[inline] fn am_anext() -> Option { diff --git a/src/class/basic.rs b/src/class/basic.rs index 24d5d3ac..402ca6fd 100644 --- a/src/class/basic.rs +++ b/src/class/basic.rs @@ -14,7 +14,7 @@ use err::{PyErr, PyResult}; use python::{Python, IntoPyPointer}; use objects::PyObject; use objects::exc; -use token::{Park, PythonPtr}; +use token::{InstancePtr, ToInstancePtr}; use typeob::PyTypeInfo; use conversion::{FromPyObject, IntoPyObject}; use callback::{PyObjectCallbackConverter, HashConverter, BoolCallbackConverter}; @@ -165,7 +165,7 @@ impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectGetAttrProtocolImpl for T where T: for<'p> PyObjectGetAttrProtocol<'p> + Park +impl PyObjectGetAttrProtocolImpl for T where T: for<'p> PyObjectGetAttrProtocol<'p> + ToInstancePtr { #[inline] fn tp_getattro() -> Option { @@ -186,7 +186,7 @@ impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectSetAttrProtocolImpl for T where T: for<'p> PyObjectSetAttrProtocol<'p> + Park +impl PyObjectSetAttrProtocolImpl for T where T: for<'p> PyObjectSetAttrProtocol<'p> + ToInstancePtr { #[inline] fn tp_setattro() -> Option { @@ -205,7 +205,7 @@ impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectDelAttrProtocolImpl for T where T: for<'p> PyObjectDelAttrProtocol<'p> + Park +impl PyObjectDelAttrProtocolImpl for T where T: for<'p> PyObjectDelAttrProtocol<'p> + ToInstancePtr { #[inline] default fn tp_delattro() -> Option { @@ -213,7 +213,7 @@ impl PyObjectDelAttrProtocolImpl for T where T: for<'p> PyObjectDelAttrProtoc } } impl PyObjectDelAttrProtocolImpl for T - where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p> + Park + where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p> + ToInstancePtr { #[inline] fn tp_delattro() -> Option { @@ -233,7 +233,7 @@ impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectStrProtocolImpl for T where T: for<'p> PyObjectStrProtocol<'p> + Park +impl PyObjectStrProtocolImpl for T where T: for<'p> PyObjectStrProtocol<'p> + ToInstancePtr { #[inline] fn tp_str() -> Option { @@ -252,7 +252,7 @@ impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectReprProtocolImpl for T where T: for<'p> PyObjectReprProtocol<'p> + Park +impl PyObjectReprProtocolImpl for T where T: for<'p> PyObjectReprProtocol<'p> + ToInstancePtr { #[inline] fn tp_repr() -> Option { @@ -296,7 +296,7 @@ impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectHashProtocolImpl for T where T: for<'p> PyObjectHashProtocol<'p> + Park +impl PyObjectHashProtocolImpl for T where T: for<'p> PyObjectHashProtocol<'p> + ToInstancePtr { #[inline] fn tp_hash() -> Option { @@ -315,7 +315,7 @@ impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectProtocol<'p> None } } -impl PyObjectBoolProtocolImpl for T where T: for<'p> PyObjectBoolProtocol<'p> + Park +impl PyObjectBoolProtocolImpl for T where T: for<'p> PyObjectBoolProtocol<'p> + ToInstancePtr { #[inline] fn nb_bool() -> Option { @@ -334,14 +334,14 @@ impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectProtocol<'p> } } impl PyObjectRichcmpProtocolImpl for T - where T: for<'p> PyObjectRichcmpProtocol<'p> + Park + where T: for<'p> PyObjectRichcmpProtocol<'p> + ToInstancePtr { #[inline] fn tp_richcompare() -> Option { unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject, op: c_int) -> *mut ffi::PyObject - where T: for<'p> PyObjectRichcmpProtocol<'p> + Park + where T: for<'p> PyObjectRichcmpProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()"); diff --git a/src/class/buffer.rs b/src/class/buffer.rs index 9b24fecf..565d0f91 100644 --- a/src/class/buffer.rs +++ b/src/class/buffer.rs @@ -10,7 +10,7 @@ use std::os::raw::c_int; use ffi; use err::PyResult; use python::Python; -use token::Park; +use token::ToInstancePtr; use typeob::PyTypeInfo; use callback::UnitCallbackConverter; @@ -45,7 +45,7 @@ impl PyBufferProtocolImpl for T { default fn tp_as_buffer() -> Option { None } } -impl<'p, T> PyBufferProtocolImpl for T where T: PyBufferProtocol<'p> + Park +impl<'p, T> PyBufferProtocolImpl for T where T: PyBufferProtocol<'p> + ToInstancePtr { #[inline] fn tp_as_buffer() -> Option { @@ -69,14 +69,14 @@ impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> } impl PyBufferGetBufferProtocolImpl for T - where T: for<'p> PyBufferGetBufferProtocol<'p> + Park + where T: for<'p> PyBufferGetBufferProtocol<'p> + ToInstancePtr { #[inline] fn cb_bf_getbuffer() -> Option { unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer, arg2: c_int) -> c_int - where T: for<'p> PyBufferGetBufferProtocol<'p> + Park + where T: for<'p> PyBufferGetBufferProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::()"); ::callback::cb_unary::(LOCATION, slf, UnitCallbackConverter, |py, slf| { diff --git a/src/class/descr.rs b/src/class/descr.rs index e2874ebc..2f5cd032 100644 --- a/src/class/descr.rs +++ b/src/class/descr.rs @@ -13,7 +13,7 @@ use python::Python; use objects::{PyType, PyObject}; use callback::{PyObjectCallbackConverter, UnitCallbackConverter}; use typeob::PyTypeInfo; -use token::Park; +use token::ToInstancePtr; use class::methods::PyMethodDef; use conversion::{IntoPyObject, FromPyObject}; @@ -67,7 +67,7 @@ impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> { None } } -impl PyDescrGetProtocolImpl for T where T: for<'p> PyDescrGetProtocol<'p> + Park +impl PyDescrGetProtocolImpl for T where T: for<'p> PyDescrGetProtocol<'p> + ToInstancePtr { fn tp_descr_get() -> Option { py_ternary_func!(PyDescrGetProtocol, T::__get__, T::Success, PyObjectCallbackConverter) @@ -81,7 +81,7 @@ impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> { None } } -impl PyDescrSetProtocolImpl for T where T: for<'p> PyDescrSetProtocol<'p> + Park +impl PyDescrSetProtocolImpl for T where T: for<'p> PyDescrSetProtocol<'p> + ToInstancePtr { fn tp_descr_set() -> Option { py_ternary_func!(PyDescrSetProtocol, T::__set__, (), UnitCallbackConverter, c_int) diff --git a/src/class/gc.rs b/src/class/gc.rs index 6e496738..75ac4378 100644 --- a/src/class/gc.rs +++ b/src/class/gc.rs @@ -9,7 +9,7 @@ use std::os::raw::{c_int, c_void}; use ffi; use python::{Python, ToPyPointer}; use callback::AbortOnDrop; -use token::{Park, PythonPtr}; +use token::{InstancePtr, ToInstancePtr}; use typeob::PyTypeInfo; pub struct PyTraverseError(c_int); @@ -93,14 +93,14 @@ impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> } #[doc(hidden)] -impl PyGCTraverseProtocolImpl for T where T: for<'p> PyGCTraverseProtocol<'p> + Park +impl PyGCTraverseProtocolImpl for T where T: for<'p> PyGCTraverseProtocol<'p> + ToInstancePtr { #[inline] fn tp_traverse() -> Option { unsafe extern "C" fn tp_traverse(slf: *mut ffi::PyObject, visit: ffi::visitproc, arg: *mut c_void) -> c_int - where T: for<'p> PyGCTraverseProtocol<'p> + Park + where T: for<'p> PyGCTraverseProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = concat!(stringify!(T), ".__traverse__()"); @@ -134,12 +134,12 @@ impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> } } -impl PyGCClearProtocolImpl for T where T: for<'p> PyGCClearProtocol<'p> + Park +impl PyGCClearProtocolImpl for T where T: for<'p> PyGCClearProtocol<'p> + ToInstancePtr { #[inline] fn tp_clear() -> Option { unsafe extern "C" fn tp_clear(slf: *mut ffi::PyObject) -> c_int - where T: for<'p> PyGCClearProtocol<'p> + Park + where T: for<'p> PyGCClearProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = concat!(stringify!(T), ".__clear__()"); diff --git a/src/class/iter.rs b/src/class/iter.rs index debaf774..75777e07 100644 --- a/src/class/iter.rs +++ b/src/class/iter.rs @@ -9,7 +9,7 @@ use ffi; use err::PyResult; use python::Python; -use token::Park; +use token::ToInstancePtr; use typeob::PyTypeInfo; use callback::PyObjectCallbackConverter; @@ -66,7 +66,7 @@ impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> } } -impl PyIterIterProtocolImpl for T where T: for<'p> PyIterIterProtocol<'p> + Park +impl PyIterIterProtocolImpl for T where T: for<'p> PyIterIterProtocol<'p> + ToInstancePtr { #[inline] fn tp_iter() -> Option { @@ -87,7 +87,7 @@ impl<'p, T> PyIterNextProtocolImpl for T } } -impl PyIterNextProtocolImpl for T where T: for<'p> PyIterNextProtocol<'p> + Park +impl PyIterNextProtocolImpl for T where T: for<'p> PyIterNextProtocol<'p> + ToInstancePtr { #[inline] fn tp_iternext() -> Option { diff --git a/src/class/macros.rs b/src/class/macros.rs index f629d6b3..74a462c5 100644 --- a/src/class/macros.rs +++ b/src/class/macros.rs @@ -8,9 +8,9 @@ macro_rules! py_unary_func { }; ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $ret_type:ty) => {{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject) -> $ret_type - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); @@ -57,9 +57,9 @@ macro_rules! py_unary_func { ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject - where T: for<'p> $trait<'p> + Park + where T: for<'p> $trait<'p> + ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); @@ -107,7 +107,7 @@ macro_rules! py_len_func { ($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject) -> $crate::ffi::Py_ssize_t - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); $crate::callback::cb_unary::(LOCATION, slf, $conv, |py, slf| { @@ -128,9 +128,9 @@ macro_rules! py_binary_func{ #[allow(unused_mut)] unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); @@ -186,9 +186,9 @@ macro_rules! py_binary_self_func{ #[allow(unused_mut)] unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> *mut $crate::ffi::PyObject - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); @@ -243,9 +243,9 @@ macro_rules! py_ssizearg_func { #[allow(unused_mut)] unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, arg: $crate::Py_ssize_t) -> *mut $crate::ffi::PyObject - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); @@ -296,9 +296,9 @@ macro_rules! py_ternary_func{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject, arg1: *mut $crate::ffi::PyObject, arg2: *mut $crate::ffi::PyObject) -> $return_type - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); let ret = $crate::std::panic::catch_unwind(|| { @@ -359,9 +359,9 @@ macro_rules! py_ternary_self_func{ arg1: *mut $crate::ffi::PyObject, arg2: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); let ret = $crate::std::panic::catch_unwind(|| { @@ -417,7 +417,7 @@ macro_rules! py_func_set{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject, name: *mut $crate::ffi::PyObject, value: *mut $crate::ffi::PyObject) -> $crate::c_int - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); $crate::callback::cb_unary_unit::(LOCATION, slf, |py, slf| { @@ -467,9 +467,9 @@ macro_rules! py_func_del{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject, name: *mut $crate::ffi::PyObject, value: *mut $crate::ffi::PyObject) -> $crate::c_int - where T: for<'p> $trait<'p> + $crate::Park + where T: for<'p> $trait<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); let ret = $crate::std::panic::catch_unwind(|| { @@ -530,9 +530,9 @@ macro_rules! py_func_set_del{ unsafe extern "C" fn wrap(slf: *mut $crate::ffi::PyObject, name: *mut $crate::ffi::PyObject, value: *mut $crate::ffi::PyObject) -> $crate::c_int - where T: for<'p> $trait<'p> + for<'p> $trait2<'p> + $crate::Park + where T: for<'p> $trait<'p> + for<'p> $trait2<'p> + $crate::ToInstancePtr { - use token::PythonPtr; + use token::InstancePtr; const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); let guard = $crate::callback::AbortOnDrop(LOCATION); let ret = $crate::std::panic::catch_unwind(|| { diff --git a/src/class/mapping.rs b/src/class/mapping.rs index 04641c80..7dba162d 100644 --- a/src/class/mapping.rs +++ b/src/class/mapping.rs @@ -9,7 +9,7 @@ use python::Python; use objects::{exc, PyObject}; use callback::{PyObjectCallbackConverter, LenResultConverter}; use conversion::{IntoPyObject, FromPyObject}; -use token::Park; +use token::ToInstancePtr; use typeob::PyTypeInfo; use class::methods::PyMethodDef; @@ -144,7 +144,7 @@ impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> } } -impl PyMappingLenProtocolImpl for T where T: for<'p> PyMappingLenProtocol<'p> + Park +impl PyMappingLenProtocolImpl for T where T: for<'p> PyMappingLenProtocol<'p> + ToInstancePtr { #[inline] fn mp_length() -> Option { @@ -164,7 +164,7 @@ impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> } } -impl PyMappingGetItemProtocolImpl for T where T: for<'p> PyMappingGetItemProtocol<'p> + Park +impl PyMappingGetItemProtocolImpl for T where T: for<'p> PyMappingGetItemProtocol<'p> + ToInstancePtr { #[inline] fn mp_subscript() -> Option { @@ -185,7 +185,7 @@ impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> } } -impl PyMappingSetItemProtocolImpl for T where T: for<'p> PyMappingSetItemProtocol<'p> + Park +impl PyMappingSetItemProtocolImpl for T where T: for<'p> PyMappingSetItemProtocol<'p> + ToInstancePtr { #[inline] fn mp_ass_subscript() -> Option { @@ -206,7 +206,7 @@ impl<'p, T> PyMappingDelItemProtocolImpl for T where T: PyMappingProtocol<'p> } } -impl PyMappingDelItemProtocolImpl for T where T: for<'p> PyMappingDelItemProtocol<'p> + Park +impl PyMappingDelItemProtocolImpl for T where T: for<'p> PyMappingDelItemProtocol<'p> + ToInstancePtr { #[inline] default fn mp_del_subscript() -> Option { @@ -216,7 +216,7 @@ impl PyMappingDelItemProtocolImpl for T where T: for<'p> PyMappingDelItemProt impl PyMappingDelItemProtocolImpl for T - where T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p> + Park + where T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p> + ToInstancePtr { #[inline] fn mp_del_subscript() -> Option { diff --git a/src/class/number.rs b/src/class/number.rs index 579a5f72..7e528d73 100644 --- a/src/class/number.rs +++ b/src/class/number.rs @@ -10,7 +10,7 @@ use callback::PyObjectCallbackConverter; use typeob::PyTypeInfo; use class::methods::PyMethodDef; use class::basic::PyObjectProtocolImpl; -use ::{c_void, IntoPyObject, FromPyObject, Park}; +use ::{c_void, IntoPyObject, FromPyObject, ToInstancePtr}; /// Number interface #[allow(unused_variables)] @@ -495,7 +495,7 @@ trait PyNumberAddProtocolImpl { impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_add() -> Option {None} } -impl PyNumberAddProtocolImpl for T where T: for<'p> PyNumberAddProtocol<'p> + Park { +impl PyNumberAddProtocolImpl for T where T: for<'p> PyNumberAddProtocol<'p> + ToInstancePtr { fn nb_add() -> Option { py_binary_func!(PyNumberAddProtocol, T::__add__, T::Success, PyObjectCallbackConverter) } @@ -507,7 +507,7 @@ trait PyNumberSubProtocolImpl { impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_subtract() -> Option {None} } -impl PyNumberSubProtocolImpl for T where T: for<'p> PyNumberSubProtocol<'p> + Park { +impl PyNumberSubProtocolImpl for T where T: for<'p> PyNumberSubProtocol<'p> + ToInstancePtr { fn nb_subtract() -> Option { py_binary_func!(PyNumberSubProtocol, T::__sub__, T::Success, PyObjectCallbackConverter) } @@ -519,7 +519,7 @@ trait PyNumberMulProtocolImpl { impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_multiply() -> Option {None} } -impl PyNumberMulProtocolImpl for T where T: for<'p> PyNumberMulProtocol<'p> + Park { +impl PyNumberMulProtocolImpl for T where T: for<'p> PyNumberMulProtocol<'p> + ToInstancePtr { fn nb_multiply() -> Option { py_binary_func!(PyNumberMulProtocol, T::__mul__, T::Success, PyObjectCallbackConverter) } @@ -531,7 +531,7 @@ trait PyNumberMatmulProtocolImpl { impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_matrix_multiply() -> Option {None} } -impl PyNumberMatmulProtocolImpl for T where T: for<'p> PyNumberMatmulProtocol<'p> + Park { +impl PyNumberMatmulProtocolImpl for T where T: for<'p> PyNumberMatmulProtocol<'p> + ToInstancePtr { fn nb_matrix_multiply() -> Option { py_binary_func!(PyNumberMatmulProtocol, T::__matmul__, T::Success, PyObjectCallbackConverter) @@ -545,7 +545,7 @@ impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_true_divide() -> Option {None} } impl PyNumberTruedivProtocolImpl for T - where T: for<'p> PyNumberTruedivProtocol<'p> + Park + where T: for<'p> PyNumberTruedivProtocol<'p> + ToInstancePtr { fn nb_true_divide() -> Option { py_binary_func!(PyNumberTruedivProtocol, @@ -560,7 +560,7 @@ impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_floor_divide() -> Option {None} } impl PyNumberFloordivProtocolImpl for T - where T: for<'p> PyNumberFloordivProtocol<'p> + Park + where T: for<'p> PyNumberFloordivProtocol<'p> + ToInstancePtr { fn nb_floor_divide() -> Option { py_binary_func!(PyNumberFloordivProtocol, @@ -574,7 +574,7 @@ trait PyNumberModProtocolImpl { impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_remainder() -> Option {None} } -impl PyNumberModProtocolImpl for T where T: for<'p> PyNumberModProtocol<'p> + Park { +impl PyNumberModProtocolImpl for T where T: for<'p> PyNumberModProtocol<'p> + ToInstancePtr { fn nb_remainder() -> Option { py_binary_func!(PyNumberModProtocol, T::__mod__, T::Success, PyObjectCallbackConverter) } @@ -586,7 +586,7 @@ trait PyNumberDivmodProtocolImpl { impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_divmod() -> Option {None} } -impl PyNumberDivmodProtocolImpl for T where T: for<'p> PyNumberDivmodProtocol<'p> + Park { +impl PyNumberDivmodProtocolImpl for T where T: for<'p> PyNumberDivmodProtocol<'p> + ToInstancePtr { fn nb_divmod() -> Option { py_binary_func!(PyNumberDivmodProtocol, T::__divmod__, T::Success, PyObjectCallbackConverter) @@ -599,7 +599,7 @@ trait PyNumberPowProtocolImpl { impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_power() -> Option {None} } -impl PyNumberPowProtocolImpl for T where T: for<'p> PyNumberPowProtocol<'p> + Park { +impl PyNumberPowProtocolImpl for T where T: for<'p> PyNumberPowProtocol<'p> + ToInstancePtr { fn nb_power() -> Option { py_ternary_func!(PyNumberPowProtocol, T::__pow__, ::Success, @@ -613,7 +613,7 @@ trait PyNumberLShiftProtocolImpl { impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_lshift() -> Option {None} } -impl PyNumberLShiftProtocolImpl for T where T: for<'p> PyNumberLShiftProtocol<'p> + Park { +impl PyNumberLShiftProtocolImpl for T where T: for<'p> PyNumberLShiftProtocol<'p> + ToInstancePtr { fn nb_lshift() -> Option { py_binary_func!(PyNumberLShiftProtocol, T::__lshift__, T::Success, PyObjectCallbackConverter) @@ -626,7 +626,7 @@ trait PyNumberRShiftProtocolImpl { impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_rshift() -> Option {None} } -impl PyNumberRShiftProtocolImpl for T where T: for<'p> PyNumberRShiftProtocol<'p> + Park { +impl PyNumberRShiftProtocolImpl for T where T: for<'p> PyNumberRShiftProtocol<'p> + ToInstancePtr { fn nb_rshift() -> Option { py_binary_func!(PyNumberRShiftProtocol, T::__rshift__, T::Success, PyObjectCallbackConverter) @@ -640,7 +640,7 @@ trait PyNumberAndProtocolImpl { impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_and() -> Option {None} } -impl PyNumberAndProtocolImpl for T where T: for<'p> PyNumberAndProtocol<'p> + Park { +impl PyNumberAndProtocolImpl for T where T: for<'p> PyNumberAndProtocol<'p> + ToInstancePtr { fn nb_and() -> Option { py_binary_func!(PyNumberAndProtocol, T::__and__, T::Success, PyObjectCallbackConverter) @@ -653,7 +653,7 @@ trait PyNumberXorProtocolImpl { impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_xor() -> Option {None} } -impl PyNumberXorProtocolImpl for T where T: for<'p> PyNumberXorProtocol<'p> + Park { +impl PyNumberXorProtocolImpl for T where T: for<'p> PyNumberXorProtocol<'p> + ToInstancePtr { fn nb_xor() -> Option { py_binary_func!(PyNumberXorProtocol, T::__xor__, T::Success, PyObjectCallbackConverter) @@ -666,7 +666,7 @@ trait PyNumberOrProtocolImpl { impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_or() -> Option {None} } -impl PyNumberOrProtocolImpl for T where T: for<'p> PyNumberOrProtocol<'p> + Park { +impl PyNumberOrProtocolImpl for T where T: for<'p> PyNumberOrProtocol<'p> + ToInstancePtr { fn nb_or() -> Option { py_binary_func!(PyNumberOrProtocol, T::__or__, T::Success, PyObjectCallbackConverter) @@ -680,7 +680,7 @@ trait PyNumberIAddProtocolImpl { impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_add() -> Option {None} } -impl PyNumberIAddProtocolImpl for T where T: for<'p> PyNumberIAddProtocol<'p> + Park { +impl PyNumberIAddProtocolImpl for T where T: for<'p> PyNumberIAddProtocol<'p> + ToInstancePtr { fn nb_inplace_add() -> Option { py_binary_self_func!(PyNumberIAddProtocol, T::__iadd__) } @@ -692,7 +692,7 @@ trait PyNumberISubProtocolImpl { impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_subtract() -> Option {None} } -impl PyNumberISubProtocolImpl for T where T: for<'p> PyNumberISubProtocol<'p> + Park { +impl PyNumberISubProtocolImpl for T where T: for<'p> PyNumberISubProtocol<'p> + ToInstancePtr { fn nb_inplace_subtract() -> Option { py_binary_self_func!(PyNumberISubProtocol, T::__isub__) } @@ -704,7 +704,7 @@ trait PyNumberIMulProtocolImpl { impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_multiply() -> Option {None} } -impl PyNumberIMulProtocolImpl for T where T: for<'p> PyNumberIMulProtocol<'p> + Park { +impl PyNumberIMulProtocolImpl for T where T: for<'p> PyNumberIMulProtocol<'p> + ToInstancePtr { fn nb_inplace_multiply() -> Option { py_binary_self_func!(PyNumberIMulProtocol, T::__imul__) } @@ -717,7 +717,7 @@ impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_matrix_multiply() -> Option {None} } impl PyNumberIMatmulProtocolImpl for T - where T: for<'p> PyNumberIMatmulProtocol<'p> + Park + where T: for<'p> PyNumberIMatmulProtocol<'p> + ToInstancePtr { fn nb_inplace_matrix_multiply() -> Option { py_binary_self_func!(PyNumberIMatmulProtocol, T::__imatmul__) @@ -731,7 +731,7 @@ impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_true_divide() -> Option {None} } impl PyNumberITruedivProtocolImpl for T - where T: for<'p> PyNumberITruedivProtocol<'p> + Park + where T: for<'p> PyNumberITruedivProtocol<'p> + ToInstancePtr { fn nb_inplace_true_divide() -> Option { py_binary_self_func!(PyNumberITruedivProtocol, T::__itruediv__) @@ -745,7 +745,7 @@ impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_floor_divide() -> Option {None} } impl PyNumberIFloordivProtocolImpl for T - where T: for<'p> PyNumberIFloordivProtocol<'p> + Park + where T: for<'p> PyNumberIFloordivProtocol<'p> + ToInstancePtr { fn nb_inplace_floor_divide() -> Option { py_binary_self_func!(PyNumberIFloordivProtocol, T::__ifloordiv__) @@ -758,7 +758,7 @@ trait PyNumberIModProtocolImpl { impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_remainder() -> Option {None} } -impl PyNumberIModProtocolImpl for T where T: for<'p> PyNumberIModProtocol<'p> + Park { +impl PyNumberIModProtocolImpl for T where T: for<'p> PyNumberIModProtocol<'p> + ToInstancePtr { fn nb_inplace_remainder() -> Option { py_binary_self_func!(PyNumberIModProtocol, T::__imod__) } @@ -770,7 +770,7 @@ trait PyNumberIPowProtocolImpl { impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_power() -> Option {None} } -impl PyNumberIPowProtocolImpl for T where T: for<'p> PyNumberIPowProtocol<'p> + Park { +impl PyNumberIPowProtocolImpl for T where T: for<'p> PyNumberIPowProtocol<'p> + ToInstancePtr { fn nb_inplace_power() -> Option { py_ternary_self_func!(PyNumberIPowProtocol, T::__ipow__) } @@ -783,7 +783,7 @@ impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_lshift() -> Option {None} } impl PyNumberILShiftProtocolImpl for T - where T: for<'p> PyNumberILShiftProtocol<'p> + Park + where T: for<'p> PyNumberILShiftProtocol<'p> + ToInstancePtr { fn nb_inplace_lshift() -> Option { py_binary_self_func!(PyNumberILShiftProtocol, T::__ilshift__) @@ -797,7 +797,7 @@ impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_rshift() -> Option {None} } impl PyNumberIRShiftProtocolImpl for T - where T: for<'p> PyNumberIRShiftProtocol<'p> + Park + where T: for<'p> PyNumberIRShiftProtocol<'p> + ToInstancePtr { fn nb_inplace_rshift() -> Option { py_binary_self_func!(PyNumberIRShiftProtocol, T::__irshift__) @@ -811,7 +811,7 @@ trait PyNumberIAndProtocolImpl { impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_and() -> Option {None} } -impl PyNumberIAndProtocolImpl for T where T: for<'p> PyNumberIAndProtocol<'p> + Park { +impl PyNumberIAndProtocolImpl for T where T: for<'p> PyNumberIAndProtocol<'p> + ToInstancePtr { fn nb_inplace_and() -> Option { py_binary_self_func!(PyNumberIAndProtocol, T::__iand__) } @@ -823,7 +823,7 @@ trait PyNumberIXorProtocolImpl { impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_xor() -> Option {None} } -impl PyNumberIXorProtocolImpl for T where T: for<'p> PyNumberIXorProtocol<'p> + Park { +impl PyNumberIXorProtocolImpl for T where T: for<'p> PyNumberIXorProtocol<'p> + ToInstancePtr { fn nb_inplace_xor() -> Option { py_binary_self_func!(PyNumberIXorProtocol, T::__ixor__) } @@ -835,7 +835,7 @@ trait PyNumberIOrProtocolImpl { impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_inplace_or() -> Option {None} } -impl PyNumberIOrProtocolImpl for T where T: for<'p> PyNumberIOrProtocol<'p> + Park { +impl PyNumberIOrProtocolImpl for T where T: for<'p> PyNumberIOrProtocol<'p> + ToInstancePtr { fn nb_inplace_or() -> Option { py_binary_self_func!(PyNumberIOrProtocol, T::__ior__) } @@ -947,7 +947,7 @@ trait PyNumberNegProtocolImpl { impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_negative() -> Option {None} } -impl PyNumberNegProtocolImpl for T where T: for<'p> PyNumberNegProtocol<'p> + Park +impl PyNumberNegProtocolImpl for T where T: for<'p> PyNumberNegProtocol<'p> + ToInstancePtr { #[inline] fn nb_negative() -> Option { @@ -961,7 +961,7 @@ trait PyNumberPosProtocolImpl { impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_positive() -> Option {None} } -impl PyNumberPosProtocolImpl for T where T: for<'p> PyNumberPosProtocol<'p> + Park +impl PyNumberPosProtocolImpl for T where T: for<'p> PyNumberPosProtocol<'p> + ToInstancePtr { fn nb_positive() -> Option { py_unary_func!(PyNumberPosProtocol, T::__pos__, T::Success, PyObjectCallbackConverter) @@ -974,7 +974,7 @@ trait PyNumberAbsProtocolImpl { impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_absolute() -> Option {None} } -impl PyNumberAbsProtocolImpl for T where T: for<'p> PyNumberAbsProtocol<'p> + Park +impl PyNumberAbsProtocolImpl for T where T: for<'p> PyNumberAbsProtocol<'p> + ToInstancePtr { fn nb_absolute() -> Option { py_unary_func!(PyNumberAbsProtocol, T::__abs__, T::Success, PyObjectCallbackConverter) @@ -987,7 +987,7 @@ trait PyNumberInvertProtocolImpl { impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_invert() -> Option {None} } -impl PyNumberInvertProtocolImpl for T where T: for<'p> PyNumberInvertProtocol<'p> + Park +impl PyNumberInvertProtocolImpl for T where T: for<'p> PyNumberInvertProtocol<'p> + ToInstancePtr { fn nb_invert() -> Option { py_unary_func!(PyNumberInvertProtocol, T::__invert__, @@ -1001,7 +1001,7 @@ trait PyNumberIntProtocolImpl { impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_int() -> Option {None} } -impl PyNumberIntProtocolImpl for T where T: for<'p> PyNumberIntProtocol<'p> + Park +impl PyNumberIntProtocolImpl for T where T: for<'p> PyNumberIntProtocol<'p> + ToInstancePtr { fn nb_int() -> Option { py_unary_func!(PyNumberIntProtocol, T::__int__, @@ -1015,7 +1015,7 @@ trait PyNumberFloatProtocolImpl { impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_float() -> Option {None} } -impl PyNumberFloatProtocolImpl for T where T: for<'p> PyNumberFloatProtocol<'p> + Park +impl PyNumberFloatProtocolImpl for T where T: for<'p> PyNumberFloatProtocol<'p> + ToInstancePtr { fn nb_float() -> Option { py_unary_func!(PyNumberFloatProtocol, T::__float__, @@ -1030,7 +1030,7 @@ impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> { default fn nb_index() -> Option {None} } impl PyNumberIndexProtocolImpl for T - where T: for<'p> PyNumberIndexProtocol<'p> + Park + where T: for<'p> PyNumberIndexProtocol<'p> + ToInstancePtr { fn nb_index() -> Option { py_unary_func!(PyNumberIndexProtocol, diff --git a/src/class/sequence.rs b/src/class/sequence.rs index ade6f64e..62446e2a 100644 --- a/src/class/sequence.rs +++ b/src/class/sequence.rs @@ -11,7 +11,7 @@ use err::{PyErr, PyResult}; use objects::exc; use objects::PyObject; use callback::{PyObjectCallbackConverter, LenResultConverter, BoolCallbackConverter}; -use token::Park; +use token::ToInstancePtr; use typeob::PyTypeInfo; use conversion::{IntoPyObject, FromPyObject}; @@ -141,7 +141,7 @@ impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> } } -impl PySequenceLenProtocolImpl for T where T: for<'p> PySequenceLenProtocol<'p> + Park +impl PySequenceLenProtocolImpl for T where T: for<'p> PySequenceLenProtocol<'p> + ToInstancePtr { #[inline] fn sq_length() -> Option { @@ -162,7 +162,7 @@ impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> } impl PySequenceGetItemProtocolImpl for T - where T: for<'p> PySequenceGetItemProtocol<'p> + Park + where T: for<'p> PySequenceGetItemProtocol<'p> + ToInstancePtr { #[inline] fn sq_item() -> Option { @@ -184,14 +184,14 @@ impl<'p, T> PySequenceSetItemProtocolImpl for T where T: PySequenceProtocol<'p> } impl PySequenceSetItemProtocolImpl for T - where T: for<'p> PySequenceSetItemProtocol<'p> + Park + where T: for<'p> PySequenceSetItemProtocol<'p> + ToInstancePtr { #[inline] fn sq_ass_item() -> Option { unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, key: ffi::Py_ssize_t, value: *mut ffi::PyObject) -> c_int - where T: for<'p> PySequenceSetItemProtocol<'p> + Park + where T: for<'p> PySequenceSetItemProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = "foo.__setitem__()"; ::callback::cb_unary_unit::(LOCATION, slf, |py, slf| { @@ -235,14 +235,14 @@ impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceProtocol<'p> } impl PySequenceDelItemProtocolImpl for T - where T: for<'p> PySequenceDelItemProtocol<'p> + Park + where T: for<'p> PySequenceDelItemProtocol<'p> + ToInstancePtr { #[inline] default fn sq_del_item() -> Option { unsafe extern "C" fn wrap(slf: *mut ffi::PyObject, key: ffi::Py_ssize_t, value: *mut ffi::PyObject) -> c_int - where T: for<'p> PySequenceDelItemProtocol<'p> + Park + where T: for<'p> PySequenceDelItemProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = "T.__detitem__()"; ::callback::cb_unary_unit::(LOCATION, slf, |py, slf| { @@ -269,7 +269,7 @@ impl PySequenceDelItemProtocolImpl for T } impl PySequenceDelItemProtocolImpl for T - where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p> + Park + where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p> + ToInstancePtr { #[inline] fn sq_del_item() -> Option { @@ -277,7 +277,7 @@ impl PySequenceDelItemProtocolImpl for T key: ffi::Py_ssize_t, value: *mut ffi::PyObject) -> c_int where T: for<'p> PySequenceSetItemProtocol<'p> + - for<'p> PySequenceDelItemProtocol<'p> + Park + for<'p> PySequenceDelItemProtocol<'p> + ToInstancePtr { const LOCATION: &'static str = "T.__set/del_item__()"; ::callback::cb_unary_unit::(LOCATION, slf, |py, slf| { @@ -326,7 +326,7 @@ impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> } impl PySequenceContainsProtocolImpl for T - where T: for<'p> PySequenceContainsProtocol<'p> + Park + where T: for<'p> PySequenceContainsProtocol<'p> + ToInstancePtr { #[inline] fn sq_contains() -> Option { @@ -348,7 +348,7 @@ impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> } impl PySequenceConcatProtocolImpl for T - where T: for<'p> PySequenceConcatProtocol<'p> + Park + where T: for<'p> PySequenceConcatProtocol<'p> + ToInstancePtr { #[inline] fn sq_concat() -> Option { @@ -370,7 +370,7 @@ impl<'p, T> PySequenceRepeatProtocolImpl for T } } -impl PySequenceRepeatProtocolImpl for T where T: for<'p> PySequenceRepeatProtocol<'p> + Park +impl PySequenceRepeatProtocolImpl for T where T: for<'p> PySequenceRepeatProtocol<'p> + ToInstancePtr { #[inline] fn sq_repeat() -> Option { @@ -392,7 +392,7 @@ impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtoco } impl PySequenceInplaceConcatProtocolImpl for T - where T: for<'p> PySequenceInplaceConcatProtocol<'p> + Park + where T: for<'p> PySequenceInplaceConcatProtocol<'p> + ToInstancePtr { #[inline] fn sq_inplace_concat() -> Option { @@ -414,7 +414,7 @@ impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtoco } impl PySequenceInplaceRepeatProtocolImpl for T - where T: for<'p> PySequenceInplaceRepeatProtocol<'p> + Park + where T: for<'p> PySequenceInplaceRepeatProtocol<'p> + ToInstancePtr { #[inline] fn sq_inplace_repeat() -> Option { diff --git a/src/conversion.rs b/src/conversion.rs index 0f7bc78e..98f71a36 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -21,7 +21,9 @@ pub trait ToPyObject { where F: FnOnce(*mut ffi::PyObject) -> R { let obj = self.to_object(py); - f(obj.as_ptr()) + let result = f(obj.as_ptr()); + py.release(obj); + result } } @@ -35,20 +37,11 @@ pub trait IntoPyObject { /// Conversion trait that allows various objects to be converted into PyTuple object. -pub trait ToPyTuple { +pub trait IntoPyTuple { /// Converts self into a PyTuple object. - fn to_py_tuple(&self, py: Python) -> PyTuple; + fn into_tuple(self, py: Python) -> PyTuple; - /// Converts self into a PyTuple object and calls the specified closure - /// on the native FFI pointer underlying the Python object. - #[inline] - fn with_borrowed_ptr(&self, py: Python, f: F) -> R - where F: FnOnce(*mut ffi::PyObject) -> R - { - let obj = self.to_py_tuple(py); - f(obj.as_ptr()) - } } @@ -135,7 +128,6 @@ impl ToPyObject for Option where T: ToPyObject { } } } - impl IntoPyObject for Option where T: IntoPyObject { fn into_object(self, py: Python) -> ::PyObject { @@ -152,9 +144,14 @@ impl ToPyObject for () { py.None() } } +impl IntoPyObject for () { + fn into_object(self, py: Python) -> PyObject { + py.None() + } +} /// Extract reference to instance from PyObject -impl<'source, T> ::FromPyObject<'source> for &'source T +impl<'source, T> FromPyObject<'source> for &'source T where T: PyTypeInfo + PyDowncastFrom { #[inline] diff --git a/src/err.rs b/src/err.rs index ea58aae1..d0409b41 100644 --- a/src/err.rs +++ b/src/err.rs @@ -7,7 +7,7 @@ use ffi; use python::{ToPyPointer, IntoPyPointer, Python, PyDowncastInto, PyClone}; use objects::{PyObject, PyType, exc}; use typeob::{PyTypeObject}; -use conversion::{ToPyObject, ToPyTuple, IntoPyObject}; +use conversion::{ToPyObject, IntoPyTuple, IntoPyObject}; /** Defines a new exception type. @@ -240,13 +240,12 @@ impl PyErr { /// `exc` is the exception type; usually one of the standard exceptions like `py.get_type::()`. /// `args` is the a tuple of arguments to pass to the exception constructor. #[inline] - pub fn new_err(py: Python, exc: PyType, args: A) -> PyErr - where A: ToPyTuple + pub fn new_err(py: Python, exc: &PyType, args: A) -> PyErr + where A: IntoPyTuple { - let pval = args.to_py_tuple(py); PyErr { - ptype: exc, - pvalue: Some(pval.into_object(py)), + ptype: exc.clone_ref(py), + pvalue: Some(args.into_tuple(py).into()), ptraceback: None } } @@ -333,13 +332,13 @@ impl PyErr { } } - //pub fn clone_ref(&self, py: Python) -> PyErr { - // PyErr { - // ptype: self.ptype.clone_ref(py), - // pvalue: self.pvalue.clone_ref(py), - // ptraceback: self.ptraceback.clone_ref(py), - // } - //} + pub fn clone_ref(&self, py: Python) -> PyErr { + PyErr { + ptype: self.ptype.clone_ref(py), + pvalue: self.pvalue.clone_ref(py), + ptraceback: self.ptraceback.clone_ref(py), + } + } } /// Converts `PyDowncastError` to Python `TypeError`. diff --git a/src/lib.rs b/src/lib.rs index fc8f3a03..4fa852c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,7 @@ //! ``` extern crate libc; +#[macro_use] extern crate log; #[allow(unused_imports)] #[macro_use] @@ -66,14 +67,15 @@ pub mod pointers; pub use pointers::PyPtr; mod token; -pub use token::{PyToken, PyObjectWithToken, Park, PythonPtr}; +pub use token::{PyToken, PyObjectWithToken, ToInstancePtr, InstancePtr}; pub use err::{PyErr, PyResult, PyDowncastError}; pub use objects::*; pub use objectprotocol::ObjectProtocol; -pub use python::{Python, ToPyPointer, IntoPyPointer, PyClone, PyDowncastFrom, PyDowncastInto}; +pub use python::{Python, ToPyPointer, IntoPyPointer, PyClone, + PyMutDowncastFrom, PyDowncastFrom, PyDowncastInto}; pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python}; -pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, ToPyTuple}; +pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, IntoPyTuple}; pub use class::{CompareOp}; pub mod class; pub use class::*; diff --git a/src/objectprotocol.rs b/src/objectprotocol.rs index d9177df9..3626935a 100644 --- a/src/objectprotocol.rs +++ b/src/objectprotocol.rs @@ -8,8 +8,8 @@ use std::cmp::Ordering; use ffi; use err::{PyErr, PyResult, self}; use python::{Python, PyDowncastInto, ToPyPointer}; -use objects::{PyObject, PyDict, PyString, PyIterator}; -use conversion::{ToPyObject, ToPyTuple}; +use objects::{PyObject, PyDict, PyString, PyIterator, PyType}; +use conversion::{ToPyObject, IntoPyTuple}; pub trait ObjectProtocol { @@ -74,14 +74,14 @@ pub trait ObjectProtocol { /// Calls the object. /// This is equivalent to the Python expression: 'self(*args, **kwargs)' fn call(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple; + where A: IntoPyTuple; /// Calls a method on the object. /// This is equivalent to the Python expression: 'self.name(*args, **kwargs)' fn call_method(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple; + where A: IntoPyTuple; /// Retrieves the hash code of the object. /// This is equivalent to the Python expression: 'hash(self)' @@ -117,6 +117,10 @@ pub trait ObjectProtocol { /// is an iterator, this returns itself. fn iter<'p>(&self, py: Python<'p>) -> PyResult>; + /// Gets the Python type object for this object's type. + #[inline] + fn get_type(&self, py: Python) -> PyType; + fn get_refcnt(&self) -> isize; } @@ -135,7 +139,7 @@ impl ObjectProtocol for T where T: ToPyPointer { /// Retrieves an attribute value. /// This is equivalent to the Python expression 'self.attr_name'. #[inline] - fn getattr(&self, py: Python, attr_name: N) -> PyResult where N: ToPyObject + fn getattr(&self, py: Python, attr_name: N) -> PyResult where N: ToPyObject { attr_name.with_borrowed_ptr(py, |attr_name| unsafe { PyObject::from_owned_ptr_or_err( @@ -260,14 +264,15 @@ impl ObjectProtocol for T where T: ToPyPointer { /// This is equivalent to the Python expression: 'self(*args, **kwargs)' #[inline] fn call(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple + where A: IntoPyTuple { - let t = args.to_py_tuple(py); - unsafe { - PyObject::from_owned_ptr_or_err( - py, - ffi::PyObject_Call(self.as_ptr(), t.as_ptr(), kwargs.as_ptr())) - } + let t = args.into_tuple(py); + let result = unsafe { + PyObject::from_borrowed_ptr_or_err( + py, ffi::PyObject_Call(self.as_ptr(), t.as_ptr(), kwargs.as_ptr())) + }; + py.release(t); + result } /// Calls a method on the object. @@ -276,14 +281,15 @@ impl ObjectProtocol for T where T: ToPyPointer { fn call_method(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple + where A: IntoPyTuple { name.with_borrowed_ptr(py, |name| unsafe { - let t = args.to_py_tuple(py); + let t = args.into_tuple(py); let ptr = ffi::PyObject_GetAttr(self.as_ptr(), name); - PyObject::from_owned_ptr_or_err( - py, - ffi::PyObject_Call(ptr, t.as_ptr(), kwargs.as_ptr())) + let result = PyObject::from_borrowed_ptr_or_err( + py, ffi::PyObject_Call(ptr, t.as_ptr(), kwargs.as_ptr())); + py.release(t); + result }) } @@ -374,6 +380,14 @@ impl ObjectProtocol for T where T: ToPyPointer { } } + /// Gets the Python type object for this object's type. + #[inline] + fn get_type(&self, py: Python) -> PyType { + unsafe { + PyType::from_type_ptr(py, (*self.as_ptr()).ob_type) + } + } + fn get_refcnt(&self) -> isize { unsafe { ffi::Py_REFCNT(self.as_ptr()) } } diff --git a/src/objects/list.rs b/src/objects/list.rs index bd883930..2c2bd3fb 100644 --- a/src/objects/list.rs +++ b/src/objects/list.rs @@ -27,6 +27,13 @@ impl PyList { } } + /// Construct a new empty list. + pub fn empty(_py: Python) -> PyList { + unsafe { + PyList(PyPtr::from_owned_ptr_or_panic(ffi::PyList_New(0))) + } + } + /// Gets the length of the list. #[inline] pub fn len(&self, _py: Python) -> usize { diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 429a1fb8..b9605d87 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -24,7 +24,6 @@ macro_rules! pyobject_nativetype( unsafe{$crate::std::mem::transmute(self)} } } - impl $crate::PyClone for $name { fn clone_ref(&self, _py: $crate::Python) -> Self { $name(unsafe{$crate::PyPtr::from_borrowed_ptr(self.as_ptr())}) @@ -79,12 +78,11 @@ macro_rules! pyobject_nativetype( } } } - impl $crate::python::PyDowncastInto for $name { fn downcast_into<'p, I>(py: $crate::Python<'p>, ob: I) -> Result> - where I: $crate::ToPyPointer + $crate::IntoPyPointer + where I: $crate::IntoPyPointer { unsafe{ let ptr = ob.into_ptr(); diff --git a/src/objects/module.rs b/src/objects/module.rs index 49d979b1..d079b6d2 100644 --- a/src/objects/module.rs +++ b/src/objects/module.rs @@ -7,7 +7,7 @@ use ffi; use std::os::raw::c_char; use std::ffi::{CStr, CString}; -use conversion::{ToPyObject, ToPyTuple}; +use conversion::{ToPyObject, IntoPyTuple}; use pointers::PyPtr; use python::{Python, ToPyPointer}; use objects::{PyObject, PyDict, PyType, exc}; @@ -77,7 +77,7 @@ impl<'p> PyModule { /// This is equivalent to the Python expression: `getattr(module, name)(*args, **kwargs)` pub fn call(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple + where A: IntoPyTuple { self.getattr(py, name)?.call(py, args, kwargs) } diff --git a/src/objects/object.rs b/src/objects/object.rs index abbdf5c7..e9881e28 100644 --- a/src/objects/object.rs +++ b/src/objects/object.rs @@ -4,8 +4,9 @@ use std; use ffi; use pointers::PyPtr; -use err::{PyResult, PyDowncastError}; +use err::{PyErr, PyResult, PyDowncastError}; use python::{Python, ToPyPointer}; +use conversion::FromPyObject; pub struct PyObject(PyPtr); @@ -56,6 +57,16 @@ impl PyObject { } } + #[inline] + pub fn from_borrowed_ptr_or_err(py: Python, ptr: *mut ffi::PyObject) -> PyResult + { + if ptr.is_null() { + Err(PyErr::fetch(py)) + } else { + Ok(PyObject(unsafe{PyPtr::from_borrowed_ptr(ptr)})) + } + } + /// Transmutes a slice of owned FFI pointers to `&[Py<'p, PyObject>]`. /// Undefined behavior if any pointer in the slice is NULL or invalid. #[inline] @@ -93,9 +104,9 @@ impl PyObject { /// Extracts some type from the Python object. /// This is a wrapper function around `FromPyObject::extract()`. #[inline] - pub fn extract<'a, D>(&'a self, py: Python) -> PyResult where D: ::conversion::FromPyObject<'a> + pub fn extract<'a, D>(&'a self, py: Python) -> PyResult where D: FromPyObject<'a> { - ::conversion::FromPyObject::extract(py, &self) + FromPyObject::extract(py, &self) } pub fn get_refcnt(&self) -> isize { diff --git a/src/objects/tuple.rs b/src/objects/tuple.rs index 4dc66fb7..e779f4cd 100644 --- a/src/objects/tuple.rs +++ b/src/objects/tuple.rs @@ -8,7 +8,7 @@ use ffi::{self, Py_ssize_t}; use err::{PyErr, PyResult}; use pointers::PyPtr; use python::{Python, ToPyPointer, IntoPyPointer}; -use conversion::{FromPyObject, ToPyObject, ToPyTuple, IntoPyObject}; +use conversion::{FromPyObject, ToPyObject, IntoPyTuple, IntoPyObject}; use objects::PyObject; use super::exc; @@ -87,14 +87,14 @@ impl PyTuple { //} } -impl ToPyTuple for PyTuple { - fn to_py_tuple(&self, _py: Python) -> PyTuple { - unsafe { PyTuple(PyPtr::from_borrowed_ptr(self.0.as_ptr())) } +impl IntoPyTuple for PyTuple { + fn into_tuple(self, _py: Python) -> PyTuple { + self } } -impl<'a> ToPyTuple for &'a str { - fn to_py_tuple(&self, py: Python) -> PyTuple { +impl<'a> IntoPyTuple for &'a str { + fn into_tuple(self, py: Python) -> PyTuple { PyTuple::new(py, &[py_coerce_expr!(self.to_object(py))]) } } @@ -114,11 +114,18 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+ ]).into() } } - - impl <$($T: ToPyObject),+> ToPyTuple for ($($T,)+) { - fn to_py_tuple(&self, py: Python) -> PyTuple { + impl <$($T: IntoPyObject),+> IntoPyObject for ($($T,)+) { + fn into_object(self, py: Python) -> PyObject { PyTuple::new(py, &[ - $(py_coerce_expr!(self.$n.to_object(py)),)+ + $(py_coerce_expr!(self.$n.into_object(py)),)+ + ]).into() + } + } + + impl <$($T: IntoPyObject),+> IntoPyTuple for ($($T,)+) { + fn into_tuple(self, py: Python) -> PyTuple { + PyTuple::new(py, &[ + $(py_coerce_expr!(self.$n.into_object(py)),)+ ]) } } @@ -186,17 +193,17 @@ impl IntoPyObject for NoArgs } /// Converts `NoArgs` to an empty Python tuple. -impl ToPyTuple for NoArgs { +impl IntoPyTuple for NoArgs { - fn to_py_tuple(&self, py: Python) -> PyTuple { + fn into_tuple(self, py: Python) -> PyTuple { PyTuple::empty(py) } } /// Converts `()` to an empty Python tuple. -impl ToPyTuple for () { +impl IntoPyTuple for () { - fn to_py_tuple(&self, py: Python) -> PyTuple { + fn into_tuple(self, py: Python) -> PyTuple { PyTuple::empty(py) } } diff --git a/src/objects/typeobject.rs b/src/objects/typeobject.rs index b1ed38e2..d0f806ef 100644 --- a/src/objects/typeobject.rs +++ b/src/objects/typeobject.rs @@ -8,9 +8,7 @@ use std::borrow::Cow; use ffi; use pointers::PyPtr; use python::{Python, ToPyPointer}; -use conversion::ToPyTuple; -use objects::{PyObject, PyDict}; -use err::PyResult; +use objects::PyObject; /// Represents a reference to a Python type object. pub struct PyType(PyPtr); @@ -52,19 +50,6 @@ impl PyType { pub fn is_instance(&self, _py: Python, obj: &T) -> bool { unsafe { ffi::PyObject_TypeCheck(obj.as_ptr(), self.as_type_ptr()) != 0 } } - - // /// Calls the type object, thus creating a new instance. - // /// This is equivalent to the Python expression: `self(*args, **kwargs)` - #[inline] - pub fn call(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult - where A: ToPyTuple - { - let args = args.to_py_tuple(py); - unsafe { - PyObject::from_owned_ptr_or_err( - py, ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr())) - } - } } impl PartialEq for PyType { diff --git a/src/pointers.rs b/src/pointers.rs index d64a442c..125557c9 100644 --- a/src/pointers.rs +++ b/src/pointers.rs @@ -22,7 +22,8 @@ impl PyPtr { /// Undefined behavior if the pointer is NULL or invalid. #[inline] pub unsafe fn from_owned_ptr(ptr: *mut ffi::PyObject) -> PyPtr { - debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0); + debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0, + format!("REFCNT: {:?} - {:?}", ptr, ffi::Py_REFCNT(ptr))); PyPtr(ptr) } @@ -59,7 +60,8 @@ impl PyPtr { /// Undefined behavior if the pointer is NULL or invalid. #[inline] pub unsafe fn from_borrowed_ptr(ptr: *mut ffi::PyObject) -> PyPtr { - debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0); + debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0, + format!("REFCNT: {:?} - {:?}", ptr, ffi::Py_REFCNT(ptr))); ffi::Py_INCREF(ptr); PyPtr::from_owned_ptr(ptr) } @@ -132,14 +134,13 @@ impl PartialEq for PyPtr { } } - /// Dropping a `PyPtr` instance decrements the reference count on the object by 1. impl Drop for PyPtr { fn drop(&mut self) { unsafe { - println!("drop PyPtr: {:?} {} {:?}", - self.0, ffi::Py_REFCNT(self.0), &self as *const _); + debug!("drop PyPtr: {:?} {} {:?}", + self.0, ffi::Py_REFCNT(self.0), &self as *const _); } let _gil_guard = Python::acquire_gil(); unsafe { ffi::Py_DECREF(self.0); } diff --git a/src/python.rs b/src/python.rs index c2bc76e9..03fd0527 100644 --- a/src/python.rs +++ b/src/python.rs @@ -9,7 +9,7 @@ use std::os::raw::c_int; use ffi; use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc}; -use token::{PyToken, Park}; +use token::{PyToken, ToInstancePtr}; use objects::{PyObject, PyType, PyBool, PyDict, PyModule}; use err::{PyErr, PyResult, PyDowncastError}; use pythonrun::GILGuard; @@ -34,9 +34,15 @@ pub trait PyDowncastFrom : Sized { /// Cast from PyObject to a concrete Python object type. fn downcast_from<'a, 'p>(Python<'p>, &'a PyObject) -> Result<&'a Self, PyDowncastError<'p>>; - } +/// Trait implemented by Python object types that allow a checked downcast. +pub trait PyMutDowncastFrom : Sized { + + /// Cast from PyObject to a concrete Python object type. + fn downcast_mut_from<'a, 'p>(Python<'p>, &'a mut PyObject) -> + Result<&'a mut Self, PyDowncastError<'p>>; +} /// Trait implemented by Python object types that allow a checked downcast. pub trait PyDowncastInto : Sized { @@ -67,7 +73,6 @@ pub trait IntoPyPointer { fn into_ptr(self) -> *mut ffi::PyObject; } - /// Convert None into a null pointer. impl<'p, T> ToPyPointer for Option<&'p T> where T: ToPyPointer { #[inline] @@ -223,18 +228,18 @@ impl<'p> Python<'p> { unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_NotImplemented()) } } - /// Execute closure `F` with Python Token instance. - pub fn with(self, f: F) -> PyResult + /// Create new python object and move T instance under python management + pub fn init(self, f: F) -> PyResult where F: FnOnce(PyToken) -> T, - T: Park + PyTypeInfo + PyObjectAlloc + T: ToInstancePtr + PyTypeInfo + PyObjectAlloc { - ::token::with(self, f) + ::token::init(self, f) } /// Release PyObject reference pub fn release(self, ob: T) where T: IntoPyPointer { unsafe { - ffi::Py_INCREF(ob.into_ptr()); + ffi::Py_DECREF(ob.into_ptr()); } } } diff --git a/src/pythonrun.rs b/src/pythonrun.rs index 66fca79d..3001d197 100644 --- a/src/pythonrun.rs +++ b/src/pythonrun.rs @@ -96,7 +96,7 @@ pub struct GILGuard { /// The Drop implementation for GILGuard will release the GIL. impl Drop for GILGuard { fn drop(&mut self) { - println!("RELEASE"); + debug!("RELEASE"); unsafe { ffi::PyGILState_Release(self.gstate) } } } @@ -108,7 +108,7 @@ impl GILGuard { /// See [prepare_freethreaded_python()](fn.prepare_freethreaded_python.html) for details. pub fn acquire() -> GILGuard { ::pythonrun::prepare_freethreaded_python(); - println!("ACQUIRE"); + debug!("ACQUIRE"); let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL GILGuard { gstate: gstate, no_send: marker::PhantomData } } diff --git a/src/token.rs b/src/token.rs index 801d5fb5..c4fdfb32 100644 --- a/src/token.rs +++ b/src/token.rs @@ -19,9 +19,9 @@ impl PyToken { /// Create new python object and move T instance under python management #[inline] -pub fn with<'p, T, F>(py: Python<'p>, f: F) -> PyResult +pub fn init<'p, T, F>(py: Python<'p>, f: F) -> PyResult where F: FnOnce(PyToken) -> T, - T: Park + PyTypeInfo + PyObjectAlloc + T: ToInstancePtr + PyTypeInfo + PyObjectAlloc { let ob = f(PyToken(PhantomData)); @@ -36,22 +36,36 @@ pub trait PyObjectWithToken : Sized { fn token<'p>(&'p self) -> Python<'p>; } +pub trait ToInstancePtr : Sized { + type Target: InstancePtr + IntoPyPointer; -pub trait Park : Sized { - type ParkTarget: PythonPtr + IntoPyPointer; + fn to_inst_ptr(&self) -> Self::Target; - fn park(&self) -> Self::ParkTarget; + unsafe fn from_owned_ptr(*mut ffi::PyObject) -> Self::Target; - unsafe fn from_owned_ptr(*mut ffi::PyObject) -> Self::ParkTarget; - - unsafe fn from_borrowed_ptr(*mut ffi::PyObject) -> Self::ParkTarget; + unsafe fn from_borrowed_ptr(*mut ffi::PyObject) -> Self::Target; } -pub trait PythonPtr : Sized { +pub trait InstancePtr : Sized { fn as_ref(&self, py: Python) -> &T; fn as_mut(&self, py: Python) -> &mut T; + fn with(&self, f: F) -> R where F: FnOnce(Python, &T) -> R + { + let gil = Python::acquire_gil(); + let py = gil.python(); + + f(py, self.as_ref(py)) + } + + fn with_mut(&self, f: F) -> R where F: FnOnce(Python, &mut T) -> R + { + let gil = Python::acquire_gil(); + let py = gil.python(); + + f(py, self.as_mut(py)) + } } diff --git a/src/typeob.rs b/src/typeob.rs index 17113601..efb58a8d 100644 --- a/src/typeob.rs +++ b/src/typeob.rs @@ -250,7 +250,7 @@ pub fn initialize_type(py: Python, module_name: Option<&str>, type_name: &str unsafe extern "C" fn tp_dealloc_callback(obj: *mut ffi::PyObject) where T: PyTypeInfo { - println!("DEALLOC: {:?}", obj); + debug!("DEALLOC: {:?}", obj); let guard = AbortOnDrop("Cannot unwind out of tp_dealloc"); let py = Python::assume_gil_acquired(); let r = ::dealloc(py, obj); diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index b7cda614..540335ac 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -72,7 +72,7 @@ fn test_buffer() { let gil = Python::acquire_gil(); let py = gil.python(); - let t = py.with(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap(); + let t = py.init(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap(); let d = PyDict::new(py); let _ = d.set_item(py, "ob", t); diff --git a/tests/test_class.rs b/tests/test_class.rs index 45ebc2fb..67b87c8d 100644 --- a/tests/test_class.rs +++ b/tests/test_class.rs @@ -79,7 +79,7 @@ struct EmptyClassWithNewPtr(PyPtr); impl EmptyClassWithNew { #[__new__] fn __new__(cls: &PyType, py: Python) -> PyResult { - py.with(|t| EmptyClassWithNew{token: t}) + py.init(|t| EmptyClassWithNew{token: t}) } } @@ -104,7 +104,7 @@ struct NewWithOneArgPtr(PyPtr); impl NewWithOneArg { #[new] fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult { - py.with(|t| NewWithOneArg{_data: arg, token: t}) + py.init(|t| NewWithOneArg{_data: arg, token: t}) } } @@ -133,7 +133,7 @@ struct NewWithTwoArgsPtr(PyPtr); impl NewWithTwoArgs { #[new] fn __new__(_cls: &PyType, py: Python, arg1: i32, arg2: i32) -> PyResult { - py.with(|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t}) + py.init(|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t}) } } @@ -173,7 +173,7 @@ fn data_is_dropped() { let drop_called1 = Arc::new(AtomicBool::new(false)); let drop_called2 = Arc::new(AtomicBool::new(false)); - let inst = py.with(|t| DataIsDropped{ + let inst = py.init(|t| DataIsDropped{ member1: TestDropCall { drop_called: drop_called1.clone() }, member2: TestDropCall { drop_called: drop_called2.clone() }, token: t @@ -206,7 +206,7 @@ fn instance_method() { let gil = Python::acquire_gil(); let py = gil.python(); - let obj = py.with(|t| InstanceMethod{member: 42, token: t}).unwrap(); + let obj = py.init(|t| InstanceMethod{member: 42, token: t}).unwrap(); assert!(obj.as_ref(py).method(py).unwrap() == 42); let d = PyDict::new(py); d.set_item(py, "obj", obj).unwrap(); @@ -233,7 +233,7 @@ fn instance_method_with_args() { let gil = Python::acquire_gil(); let py = gil.python(); - let obj = py.with(|t| InstanceMethodWithArgs{member: 7, token: t}).unwrap(); + let obj = py.init(|t| InstanceMethodWithArgs{member: 7, token: t}).unwrap(); assert!(obj.as_ref(py).method(py, 6).unwrap() == 42); let d = PyDict::new(py); d.set_item(py, "obj", obj).unwrap(); @@ -297,7 +297,7 @@ struct StaticMethodPtr(PyPtr); impl StaticMethod { #[new] fn __new__(cls: &PyType, py: Python) -> PyResult { - py.with(|t| StaticMethod{token: t}) + py.init(|t| StaticMethod{token: t}) } //#[staticmethod] @@ -364,7 +364,7 @@ fn gc_integration() { let py = gil.python(); let drop_called = Arc::new(AtomicBool::new(false)); - let inst = py.with(|t| GCIntegration{ + let inst = py.init(|t| GCIntegration{ self_ref: RefCell::new(py.None()), dropped: TestDropCall { drop_called: drop_called.clone() }, token: t}).unwrap(); @@ -397,14 +397,14 @@ fn len() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py.with(|t| Len{l: 10, token: t}).unwrap(); + let inst = py.init(|t| Len{l: 10, token: t}).unwrap(); py_assert!(py, inst, "len(inst) == 10"); unsafe { assert_eq!(ffi::PyObject_Size(inst.as_ptr()), 10); assert_eq!(ffi::PyMapping_Size(inst.as_ptr()), 10); } - let inst = py.with(|t| Len{l: (isize::MAX as usize) + 1, token: t}).unwrap(); + let inst = py.init(|t| Len{l: (isize::MAX as usize) + 1, token: t}).unwrap(); py_expect_exception!(py, inst, "len(inst)", OverflowError); } @@ -464,7 +464,7 @@ fn string_methods() { let gil = Python::acquire_gil(); let py = gil.python(); - let obj = py.with(|t| StringMethods{token: t}).unwrap(); + let obj = py.init(|t| StringMethods{token: t}).unwrap(); py_assert!(py, obj, "str(obj) == 'str'"); py_assert!(py, obj, "repr(obj) == 'repr'"); py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'"); @@ -497,10 +497,10 @@ fn comparisons() { let gil = Python::acquire_gil(); let py = gil.python(); - let zero = py.with(|t| Comparisons{val: 0, token: t}).unwrap(); - let one = py.with(|t| Comparisons{val: 1, token: t}).unwrap(); - let ten = py.with(|t| Comparisons{val: 10, token: t}).unwrap(); - let minus_one = py.with(|t| Comparisons{val: -1, token: t}).unwrap(); + let zero = py.init(|t| Comparisons{val: 0, token: t}).unwrap(); + let one = py.init(|t| Comparisons{val: 1, token: t}).unwrap(); + let ten = py.init(|t| Comparisons{val: 10, token: t}).unwrap(); + let minus_one = py.init(|t| Comparisons{val: -1, token: t}).unwrap(); py_assert!(py, one, "hash(one) == 1"); py_assert!(py, ten, "hash(ten) == 10"); py_assert!(py, minus_one, "hash(minus_one) == -2"); @@ -537,7 +537,7 @@ fn sequence() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| Sequence{token: t}).unwrap(); + let c = py.init(|t| Sequence{token: t}).unwrap(); py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]"); py_expect_exception!(py, c, "c['abc']", TypeError); } @@ -563,11 +563,11 @@ fn callable() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| Callable{token: t}).unwrap(); + let c = py.init(|t| Callable{token: t}).unwrap(); py_assert!(py, c, "callable(c)"); py_assert!(py, c, "c(7) == 42"); - let nc = py.with(|t| Comparisons{val: 0, token: t}).unwrap(); + let nc = py.init(|t| Comparisons{val: 0, token: t}).unwrap(); py_assert!(py, nc, "not callable(nc)"); } @@ -595,7 +595,7 @@ fn setitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| SetItem{key: 0, val: 0, token: t}).unwrap(); + let c = py.init(|t| SetItem{key: 0, val: 0, token: t}).unwrap(); py_run!(py, c, "c[1] = 2"); assert_eq!(c.as_ref(py).key, 1); assert_eq!(c.as_ref(py).val, 2); @@ -624,7 +624,7 @@ fn delitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| DelItem{key:0, token:t}).unwrap(); + let c = py.init(|t| DelItem{key:0, token:t}).unwrap(); py_run!(py, c, "del c[1]"); assert_eq!(c.as_ref(py).key, 1); py_expect_exception!(py, c, "c[1] = 2", NotImplementedError); @@ -657,7 +657,7 @@ fn setdelitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| SetDelItem{val: None, token: t}).unwrap(); + let c = py.init(|t| SetDelItem{val: None, token: t}).unwrap(); py_run!(py, c, "c[1] = 2"); assert_eq!(c.as_ref(py).val, Some(2)); py_run!(py, c, "del c[1]"); @@ -682,7 +682,7 @@ fn reversed() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| Reversed{token: t}).unwrap(); + let c = py.init(|t| Reversed{token: t}).unwrap(); py_run!(py, c, "assert reversed(c) == 'I am reversed'"); } @@ -704,7 +704,7 @@ fn contains() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| Contains{token: t}).unwrap(); + let c = py.init(|t| Contains{token: t}).unwrap(); py_run!(py, c, "assert 1 in c"); py_run!(py, c, "assert -1 not in c"); py_expect_exception!(py, c, "assert 'wrong type' not in c", TypeError); @@ -743,7 +743,7 @@ fn unary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| UnaryArithmetic{token: t}).unwrap(); + let c = py.init(|t| UnaryArithmetic{token: t}).unwrap(); py_run!(py, c, "assert -c == 'neg'"); py_run!(py, c, "assert +c == 'pos'"); py_run!(py, c, "assert abs(c) == 'abs'"); @@ -806,7 +806,7 @@ fn binary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| BinaryArithmetic{token: t}).unwrap(); + let c = py.init(|t| BinaryArithmetic{token: t}).unwrap(); py_run!(py, c, "assert c + c == 'BA + BA'"); py_run!(py, c, "assert c + 1 == 'BA + 1'"); py_run!(py, c, "assert 1 + c == '1 + BA'"); @@ -883,7 +883,7 @@ fn rich_comparisons() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| RichComparisons{token: t}).unwrap(); + let c = py.init(|t| RichComparisons{token: t}).unwrap(); py_run!(py, c, "assert (c < c) == 'RC < RC'"); py_run!(py, c, "assert (c < 1) == 'RC < 1'"); py_run!(py, c, "assert (1 < c) == 'RC > 1'"); @@ -909,7 +909,7 @@ fn rich_comparisons_python_3_type_error() { let gil = Python::acquire_gil(); let py = gil.python(); - let c2 = py.with(|t| RichComparisons2{py: t}).unwrap(); + let c2 = py.init(|t| RichComparisons2{py: t}).unwrap(); py_expect_exception!(py, c2, "c2 < c2", TypeError); py_expect_exception!(py, c2, "c2 < 1", TypeError); py_expect_exception!(py, c2, "1 < c2", TypeError); @@ -994,28 +994,28 @@ fn inplace_operations() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| InPlaceOperations{value: 0, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 0, token: t}).unwrap(); py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'"); - let c = py.with(|t| InPlaceOperations{value:10, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value:10, token: t}).unwrap(); py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'"); - let c = py.with(|t| InPlaceOperations{value: 3, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 3, token: t}).unwrap(); py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'"); - let c = py.with(|t| InPlaceOperations{value: 3, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 3, token: t}).unwrap(); py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'"); - let c = py.with(|t| InPlaceOperations{value: 12, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap(); py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'"); - let c = py.with(|t| InPlaceOperations{value: 12, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap(); py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'"); - let c = py.with(|t| InPlaceOperations{value: 12, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap(); py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'"); - let c = py.with(|t| InPlaceOperations{value: 12, token: t}).unwrap(); + let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap(); py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'"); } @@ -1053,7 +1053,7 @@ fn context_manager() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.with(|t| ContextManager{exit_called: false, token: t}).unwrap(); + let c = py.init(|t| ContextManager{exit_called: false, token: t}).unwrap(); py_run!(py, c, "with c as x:\n assert x == 42"); assert!(c.as_ref(py).exit_called); @@ -1101,7 +1101,7 @@ fn class_with_properties() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py.with(|t| ClassWithProperties{num: 10, token: t}).unwrap(); + let inst = py.init(|t| ClassWithProperties{num: 10, token: t}).unwrap(); py_run!(py, inst, "assert inst.get_num() == 10"); py_run!(py, inst, "assert inst.get_num() == inst.DATA"); diff --git a/tests/test_slice.rs b/tests/test_slice.rs index 4ba2e254..484ca92c 100644 --- a/tests/test_slice.rs +++ b/tests/test_slice.rs @@ -51,7 +51,7 @@ fn test_cls_impl() { let gil = Python::acquire_gil(); let py = gil.python(); - let ob = py.with(|t| Test{token: t}).unwrap(); + let ob = py.init(|t| Test{token: t}).unwrap(); let d = PyDict::new(py); d.set_item(py, "ob", ob).unwrap();