various cleanups

This commit is contained in:
Nikolay Kim 2017-05-24 22:43:07 -07:00
parent f3176dacfc
commit 0979653b98
20 changed files with 594 additions and 526 deletions

View File

@ -116,11 +116,11 @@ pub const CONTEXT: Proto = Proto {
MethodProto::Unary{
name: "__enter__",
pyres: true,
proto: "_pyo3::class::context::PyContextEnterProtocol"},
proto: "::pyo3::class::context::PyContextEnterProtocol"},
MethodProto::Quaternary {
name: "__exit__",
arg1: "ExcType", arg2: "ExcValue", arg3: "Traceback",
proto: "_pyo3::class::context::PyContextExitProtocol"},
proto: "::pyo3::class::context::PyContextExitProtocol"},
],
py_methods: &[
PyMethod {
@ -142,23 +142,23 @@ pub const DESCR: Proto = Proto {
arg1: "Inst",
arg2: "Owner",
pyres: true,
proto: "_pyo3::class::descr::PyDescrGetProtocol"},
proto: "::pyo3::class::descr::PyDescrGetProtocol"},
MethodProto::Ternary {
name: "__set__",
arg1: "Inst",
arg2: "Value",
pyres: true,
proto: "_pyo3::class::descr::PyDescrSetProtocol"},
proto: "::pyo3::class::descr::PyDescrSetProtocol"},
MethodProto::Binary {
name: "__det__",
arg: "Inst",
pyres: false,
proto: "_pyo3::class::descr::PyDescrDelProtocol"},
proto: "::pyo3::class::descr::PyDescrDelProtocol"},
MethodProto::Binary {
name: "__set_name__",
arg: "Inst",
pyres: false,
proto: "_pyo3::class::descr::PyDescrSetNameProtocol"},
proto: "::pyo3::class::descr::PyDescrSetNameProtocol"},
],
py_methods: &[
PyMethod {
@ -179,11 +179,11 @@ pub const ITER: Proto = Proto {
MethodProto::Unary{
name: "__iter__",
pyres: true,
proto: "_pyo3::class::iter::PyIterIterProtocol"},
proto: "::pyo3::class::iter::PyIterIterProtocol"},
MethodProto::Unary{
name: "__next__",
pyres: true,
proto: "_pyo3::class::iter::PyIterNextProtocol"},
proto: "::pyo3::class::iter::PyIterNextProtocol"},
],
};
@ -296,249 +296,249 @@ pub const NUM: Proto = Proto {
name: "__add__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberAddProtocol"},
proto: "::pyo3::class::number::PyNumberAddProtocol"},
MethodProto::Binary {
name: "__sub__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberSubProtocol"},
proto: "::pyo3::class::number::PyNumberSubProtocol"},
MethodProto::Binary {
name: "__mul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberMulProtocol"},
proto: "::pyo3::class::number::PyNumberMulProtocol"},
MethodProto::Binary {
name: "__matmul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberMatmulProtocol"},
proto: "::pyo3::class::number::PyNumberMatmulProtocol"},
MethodProto::Binary {
name: "__truediv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberTruedivProtocol"},
proto: "::pyo3::class::number::PyNumberTruedivProtocol"},
MethodProto::Binary {
name: "__floordiv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberFloordivProtocol"},
proto: "::pyo3::class::number::PyNumberFloordivProtocol"},
MethodProto::Binary {
name: "__mod__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberModProtocol"},
proto: "::pyo3::class::number::PyNumberModProtocol"},
MethodProto::Binary {
name: "__divmod__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberDivmodProtocol"},
proto: "::pyo3::class::number::PyNumberDivmodProtocol"},
MethodProto::Ternary {
name: "__pow__",
arg1: "Other",
arg2: "Modulo",
pyres: true,
proto: "_pyo3::class::number::PyNumberPowProtocol"},
proto: "::pyo3::class::number::PyNumberPowProtocol"},
MethodProto::Binary {
name: "__lshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberLShiftProtocol"},
proto: "::pyo3::class::number::PyNumberLShiftProtocol"},
MethodProto::Binary {
name: "__rshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRShiftProtocol"},
proto: "::pyo3::class::number::PyNumberRShiftProtocol"},
MethodProto::Binary {
name: "__and__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberAndProtocol"},
proto: "::pyo3::class::number::PyNumberAndProtocol"},
MethodProto::Binary {
name: "__xor__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberXorProtocol"},
proto: "::pyo3::class::number::PyNumberXorProtocol"},
MethodProto::Binary {
name: "__or__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberOrProtocol"},
proto: "::pyo3::class::number::PyNumberOrProtocol"},
MethodProto::Binary {
name: "__radd__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRAddProtocol"},
proto: "::pyo3::class::number::PyNumberRAddProtocol"},
MethodProto::Binary {
name: "__rsub__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRSubProtocol"},
proto: "::pyo3::class::number::PyNumberRSubProtocol"},
MethodProto::Binary {
name: "__rmul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRMulProtocol"},
proto: "::pyo3::class::number::PyNumberRMulProtocol"},
MethodProto::Binary {
name: "__rmatmul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRMatmulProtocol"},
proto: "::pyo3::class::number::PyNumberRMatmulProtocol"},
MethodProto::Binary {
name: "__rtruediv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRTruedivProtocol"},
proto: "::pyo3::class::number::PyNumberRTruedivProtocol"},
MethodProto::Binary {
name: "__rfloordiv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRFloordivProtocol"},
proto: "::pyo3::class::number::PyNumberRFloordivProtocol"},
MethodProto::Binary {
name: "__rmod__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRModProtocol"},
proto: "::pyo3::class::number::PyNumberRModProtocol"},
MethodProto::Binary {
name: "__rdivmod__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRDivmodProtocol"},
proto: "::pyo3::class::number::PyNumberRDivmodProtocol"},
MethodProto::Ternary {
name: "__rpow__",
arg1: "Other",
arg2: "Modulo",
pyres: true,
proto: "_pyo3::class::number::PyNumberRPowProtocol"},
proto: "::pyo3::class::number::PyNumberRPowProtocol"},
MethodProto::Binary {
name: "__rlshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRLShiftProtocol"},
proto: "::pyo3::class::number::PyNumberRLShiftProtocol"},
MethodProto::Binary {
name: "__rrshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRRShiftProtocol"},
proto: "::pyo3::class::number::PyNumberRRShiftProtocol"},
MethodProto::Binary {
name: "__rand__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRAndProtocol"},
proto: "::pyo3::class::number::PyNumberRAndProtocol"},
MethodProto::Binary {
name: "__rxor__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberRXorProtocol"},
proto: "::pyo3::class::number::PyNumberRXorProtocol"},
MethodProto::Binary {
name: "__ror__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberROrProtocol"},
proto: "::pyo3::class::number::PyNumberROrProtocol"},
MethodProto::Binary {
name: "__iadd__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIAddProtocol"},
proto: "::pyo3::class::number::PyNumberIAddProtocol"},
MethodProto::Binary {
name: "__isub__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberISubProtocol"},
proto: "::pyo3::class::number::PyNumberISubProtocol"},
MethodProto::Binary {
name: "__imul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIMulProtocol"},
proto: "::pyo3::class::number::PyNumberIMulProtocol"},
MethodProto::Binary {
name: "__imatmul__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIMatmulProtocol"},
proto: "::pyo3::class::number::PyNumberIMatmulProtocol"},
MethodProto::Binary {
name: "__itruediv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberITruedivProtocol"},
proto: "::pyo3::class::number::PyNumberITruedivProtocol"},
MethodProto::Binary {
name: "__ifloordiv__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIFloordivProtocol"},
proto: "::pyo3::class::number::PyNumberIFloordivProtocol"},
MethodProto::Binary {
name: "__imod__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIModProtocol"},
proto: "::pyo3::class::number::PyNumberIModProtocol"},
MethodProto::Ternary {
name: "__ipow__",
arg1: "Other",
arg2: "Modulo",
pyres: true,
proto: "_pyo3::class::number::PyNumberIPowProtocol"},
proto: "::pyo3::class::number::PyNumberIPowProtocol"},
MethodProto::Binary {
name: "__ilshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberILShiftProtocol"},
proto: "::pyo3::class::number::PyNumberILShiftProtocol"},
MethodProto::Binary {
name: "__irshift__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIRShiftProtocol"},
proto: "::pyo3::class::number::PyNumberIRShiftProtocol"},
MethodProto::Binary {
name: "__iand__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIAndProtocol"},
proto: "::pyo3::class::number::PyNumberIAndProtocol"},
MethodProto::Binary {
name: "__ixor__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIXorProtocol"},
proto: "::pyo3::class::number::PyNumberIXorProtocol"},
MethodProto::Binary {
name: "__ior__",
arg: "Other",
pyres: true,
proto: "_pyo3::class::number::PyNumberIOrProtocol"},
proto: "::pyo3::class::number::PyNumberIOrProtocol"},
MethodProto::Unary {
name: "__neg__",
pyres: true,
proto: "_pyo3::class::number::PyNumberNegProtocol"},
proto: "::pyo3::class::number::PyNumberNegProtocol"},
MethodProto::Unary {
name: "__pos__",
pyres: true,
proto: "_pyo3::class::number::PyNumberPosProtocol"},
proto: "::pyo3::class::number::PyNumberPosProtocol"},
MethodProto::Unary {
name: "__abs__",
pyres: true,
proto: "_pyo3::class::number::PyNumberAbsProtocol"},
proto: "::pyo3::class::number::PyNumberAbsProtocol"},
MethodProto::Unary {
name: "__invert__",
pyres: true,
proto: "_pyo3::class::number::PyNumberInvertProtocol"},
proto: "::pyo3::class::number::PyNumberInvertProtocol"},
MethodProto::Unary {
name: "__complex__",
pyres: true,
proto: "_pyo3::class::number::PyNumberComplexProtocol"},
proto: "::pyo3::class::number::PyNumberComplexProtocol"},
MethodProto::Unary {
name: "__int__",
pyres: true,
proto: "_pyo3::class::number::PyNumberIntProtocol"},
proto: "::pyo3::class::number::PyNumberIntProtocol"},
MethodProto::Unary {
name: "__float__",
pyres: true,
proto: "_pyo3::class::number::PyNumberFloatProtocol"},
proto: "::pyo3::class::number::PyNumberFloatProtocol"},
MethodProto::Unary {
name: "__round__",
pyres: true,
proto: "_pyo3::class::number::PyNumberRoundProtocol"},
proto: "::pyo3::class::number::PyNumberRoundProtocol"},
MethodProto::Unary {
name: "__index__",
pyres: true,
proto: "_pyo3::class::number::PyNumberIndexProtocol"},
proto: "::pyo3::class::number::PyNumberIndexProtocol"},
],
py_methods: &[
PyMethod {

View File

@ -45,19 +45,19 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item(
quote! {fn test(&self)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
sig.decl.output = tmp.output.clone();
if pyres {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type Success = #succ;
type Result = #ty;
}
}
} else {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type Result = #ty;
}
}
@ -72,18 +72,18 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg: <#cls as #p<'a>>::#arg_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg: <#cls as #p<'p>>::#arg_name)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg: Option<<#cls as #p<'a>>::#arg_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg: Option<<#cls as #p<'p>>::#arg_name>)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2);
if pyres {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type #arg_name = #arg_ty;
type Success = #succ;
type Result = #ty;
@ -91,7 +91,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
}
} else {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type #arg_name = #arg_ty;
type Result = #ty;
}
@ -110,21 +110,21 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg1: <#cls as #p<'a>>::#arg1_name,
arg2: <#cls as #p<'a>>::#arg2_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg1: <#cls as #p<'p>>::#arg1_name,
arg2: <#cls as #p<'p>>::#arg2_name)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg1: Option<<#cls as #p<'a>>::#arg1_name>,
arg2: Option<<#cls as #p<'a>>::#arg2_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg1: Option<<#cls as #p<'p>>::#arg1_name>,
arg2: Option<<#cls as #p<'p>>::#arg2_name>)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2);
modify_arg_ty(sig, 2, &tmp, &tmp2);
if pyres {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty;
type Success = #succ;
@ -133,7 +133,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
}
} else {
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty;
type Result = #ty;
@ -144,34 +144,34 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
MethodProto::Quaternary{name: _, arg1, arg2, arg3, proto} => {
let p = syn::Ident::from(proto);
let arg1_name = syn::Ident::from(arg1);
let arg1_ty = get_arg_ty(sig, 2);
let arg1_ty = get_arg_ty(sig, 1);
let arg2_name = syn::Ident::from(arg2);
let arg2_ty = get_arg_ty(sig, 3);
let arg2_ty = get_arg_ty(sig, 2);
let arg3_name = syn::Ident::from(arg3);
let arg3_ty = get_arg_ty(sig, 4);
let arg3_ty = get_arg_ty(sig, 3);
let succ = get_res_success(ty);
// rewrite ty
let tmp = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg1: <#cls as #p<'a>>::#arg1_name,
arg2: <#cls as #p<'a>>::#arg2_name,
arg3: <#cls as #p<'a>>::#arg3_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg1: <#cls as #p<'p>>::#arg1_name,
arg2: <#cls as #p<'p>>::#arg2_name,
arg3: <#cls as #p<'p>>::#arg3_name)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item(
quote! {fn test(
&self,
arg1: Option<<#cls as #p<'a>>::#arg1_name>,
arg2: Option<<#cls as #p<'a>>::#arg2_name>,
arg3: Option<<#cls as #p<'a>>::#arg3_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap());
arg1: Option<<#cls as #p<'p>>::#arg1_name>,
arg2: Option<<#cls as #p<'p>>::#arg2_name>,
arg3: Option<<#cls as #p<'p>>::#arg3_name>)
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2);
modify_arg_ty(sig, 2, &tmp, &tmp2);
modify_arg_ty(sig, 3, &tmp, &tmp2);
quote! {
impl<'a> #p<'a> for #cls {
impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty;
type #arg3_name = #arg3_ty;
@ -257,18 +257,18 @@ fn modify_arg_ty(sig: &mut syn::MethodSig, idx: usize,
{
let arg = sig.decl.inputs[idx].clone();
match arg {
syn::FnArg::Captured(_, ref arg_ty) => {
syn::FnArg::Captured(ref pat, ref arg_ty) => {
match arg_ty {
&syn::Ty::Path(_, ref path) => {
let seg = path.segments.last().unwrap().clone();
if seg.ident.as_ref() == "Option" {
sig.decl.inputs[idx] = decl2.inputs[idx].clone();
sig.decl.inputs[idx] = fix_name(pat, &decl2.inputs[idx]);
} else {
sig.decl.inputs[idx] = decl1.inputs[idx].clone();
sig.decl.inputs[idx] = fix_name(pat, &decl1.inputs[idx]);
}
},
_ => {
sig.decl.inputs[idx] = decl1.inputs[idx].clone();
sig.decl.inputs[idx] = fix_name(pat, &decl1.inputs[idx]);
}
}
},
@ -278,3 +278,11 @@ fn modify_arg_ty(sig: &mut syn::MethodSig, idx: usize,
sig.decl.output = decl1.output.clone();
}
fn fix_name(pat: &syn::Pat, arg: &syn::FnArg) -> syn::FnArg {
match arg {
&syn::FnArg::Captured(_, ref arg_ty) =>
syn::FnArg::Captured(pat.clone(), arg_ty.clone()),
_ => panic!("func.rs::296"),
}
}

View File

@ -141,11 +141,11 @@ impl<'a> FnSpec<'a> {
fn check_arg_ty_and_optional<'a>(name: &'a syn::Ident, ty: &'a syn::Ty) -> Option<&'a syn::Ty> {
match ty {
&syn::Ty::Path(ref qs, ref path) => {
if let &Some(ref qs) = qs {
panic!("explicit Self type in a 'qualified path' is not supported: {:?} - {:?}",
name, qs);
}
&syn::Ty::Path(_, ref path) => {
//if let &Some(ref qs) = qs {
// panic!("explicit Self type in a 'qualified path' is not supported: {:?} - {:?}",
// name, qs);
//}
if let Some(segment) = path.segments.last() {
match segment.ident.as_ref() {

View File

@ -22,6 +22,7 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
const #dummy_const: () = {
extern crate pyo3 as _pyo3;
use std;
use pyo3::python::IntoPythonPointer;
#tokens
};
@ -32,7 +33,7 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
let cls_name = quote! { #cls }.as_str().to_string();
quote! {
impl _pyo3::class::typeob::PyTypeInfo for #cls {
impl _pyo3::typeob::PyTypeInfo for #cls {
type Type = #cls;
#[inline]
@ -43,7 +44,7 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
#[inline]
fn offset() -> isize {
let align = std::mem::align_of::<#cls>();
let bs = <#base as _pyo3::class::typeob::PyTypeInfo>::size();
let bs = <#base as _pyo3::typeob::PyTypeInfo>::size();
// round base_size up to next multiple of align
((bs + align - 1) / align * align) as isize
@ -58,5 +59,28 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
unsafe { &mut TYPE_OBJECT }
}
}
impl _pyo3::IntoPyObject for #cls {
#[inline]
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
{
let ptr = py.init(self).into_ptr();
_pyo3::PyObject::from_owned_ptr(py, ptr)
}
}
//impl<'p> _pyo3::python::AsPy<'p> for &'p #cls {
// #[inline]
// fn py<'a>(&'a self) -> _pyo3::Python<'p> {
// unsafe { _pyo3::python::Python::assume_gil_acquired() }
// }
//}
impl<'p> _pyo3::python::AsPy<'p> for &'p mut #cls {
#[inline]
fn py<'a>(&'a self) -> _pyo3::Python<'p> {
unsafe { _pyo3::python::Python::assume_gil_acquired() }
}
}
}
}

View File

@ -9,11 +9,9 @@ pub fn gen_py_method<'a>(cls: &Box<syn::Ty>, name: &syn::Ident,
sig: &mut syn::MethodSig, meth_attrs: &mut Vec<syn::Attribute>) -> Tokens
{
check_generic(name, sig);
println!("====0");
let spec = FnSpec::parse(name, sig, meth_attrs);
println!("====1");
match spec.tp {
FnType::Fn =>
impl_py_method_def(name, &impl_wrap(cls, name, &spec)),
@ -46,26 +44,40 @@ pub fn impl_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens
args: *mut _pyo3::ffi::PyObject,
kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
{
const LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#name), "()");
_pyo3::callback::handle_callback(
LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py|
{
let args: _pyo3::PyTuple =
_pyo3::PyObject::from_borrowed_ptr(py, args).unchecked_cast_into();
let kwargs: Option<_pyo3::PyDict> = _pyo3::argparse::get_kwargs(py, kwargs);
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
_pyo3::argparse::get_kwargs(py, kwargs);
let ret = {
#body
};
_pyo3::PyDrop::release_ref(args, py);
_pyo3::PyDrop::release_ref(kwargs, py);
ret
})
#body
})
}
}
}
/// Generate function wrapper for protocol method (PyCFunction, PyCFunctionWithKeywords)
pub fn impl_proto_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens {
let cb = impl_call(cls, name, &spec);
let body = impl_arg_params(&spec, cb);
quote! {
unsafe extern "C" fn wrap<'p>(
slf: *mut _pyo3::ffi::PyObject,
args: *mut _pyo3::ffi::PyObject,
kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
{
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
_pyo3::argparse::get_kwargs(py, kwargs);
#body
})
}
}
}
/// Generate function wrapper (PyCFunction, PyCFunctionWithKeywords)
pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens {
@ -79,20 +91,13 @@ pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> To
{
const LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#name), "()");
_pyo3::callback::handle_callback(
LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py|
{
let args: _pyo3::PyTuple =
_pyo3::PyObject::from_borrowed_ptr(py, args).unchecked_cast_into();
let kwargs: Option<_pyo3::PyDict> = _pyo3::argparse::get_kwargs(py, kwargs);
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
_pyo3::argparse::get_kwargs(py, kwargs);
let ret = {
#body
};
_pyo3::PyDrop::release_ref(args, py);
_pyo3::PyDrop::release_ref(kwargs, py);
ret
})
#body
})
}
}
}
@ -101,21 +106,16 @@ pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> To
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
fn impl_wrap_getter(cls: &Box<syn::Ty>, name: &syn::Ident, _spec: &FnSpec) -> Tokens {
quote! {
unsafe extern "C" fn wrap (slf: *mut _pyo3::ffi::PyObject,
_: *mut _pyo3::c_void)
-> *mut _pyo3::ffi::PyObject
unsafe extern "C" fn wrap(slf: *mut _pyo3::ffi::PyObject,
_: *mut _pyo3::c_void)
-> *mut _pyo3::ffi::PyObject
{
const LOCATION: &'static str = concat!(
stringify!(#cls), ".getter_", stringify!(#name), "()");
_pyo3::callback::handle_callback(
LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py|
{
let slf = _pyo3::PyObject::from_borrowed_ptr(
py, slf).unchecked_cast_into::<#cls>();
let ret = slf.#name(py);
_pyo3::PyDrop::release_ref(slf, py);
ret
})
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
slf.#name(py)
})
}
}
}
@ -131,24 +131,18 @@ fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tok
{
const LOCATION: &'static str = concat!(
stringify!(#cls), ".setter", stringify!(#name), "()");
_pyo3::callback::handle_callback(
LOCATION, _pyo3::callback::UnitCallbackConverter, |py|
{
let slf = _pyo3::PyObject::from_borrowed_ptr(py, slf)
.unchecked_cast_into::<#cls>();
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
_pyo3::callback::handle(LOCATION, _pyo3::callback::UnitCallbackConverter, |py| {
let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
let ret = match <#val_ty as _pyo3::FromPyObject>::extract(py, &value) {
Ok(val) => {
let ret = slf.#name(py, val);
ret.map(|o| ())
}
Err(e) => Err(e)
};
_pyo3::PyDrop::release_ref(slf, py);
_pyo3::PyDrop::release_ref(value, py);
ret
})
match <#val_ty as _pyo3::FromPyObject>::extract(&value) {
Ok(val) => {
let ret = slf.#name(val);
ret.map(|o| ())
}
Err(e) => Err(e)
}
})
}
}
}
@ -156,29 +150,26 @@ fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tok
fn impl_call(cls: &Box<syn::Ty>, fname: &syn::Ident, spec: &FnSpec) -> Tokens {
let names: Vec<&syn::Ident> = spec.args.iter().map(|item| item.name).collect();
quote! {
{
let slf = _pyo3::PyObject::from_borrowed_ptr(py, slf).unchecked_cast_into::<#cls>();
let ret = slf.#fname(py, #(#names),*);
_pyo3::PyDrop::release_ref(slf, py);
ret
}
}
quote! {{
let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
slf.as_mut().#fname(#(#names),*)
}}
}
fn impl_class_new(cls: &Box<syn::Ty>, fname: &syn::Ident, spec: &FnSpec) -> Tokens {
let names: Vec<&syn::Ident> = spec.args.iter().map(|item| item.name).collect();
quote! {
{
let cls = _pyo3::PyType::from_type_ptr(py, cls);
let ret = #cls::#fname(&cls, py, #(#names),*);
_pyo3::PyDrop::release_ref(cls, py);
ret
}
}
quote! {{
let cls: _pyo3::Py<_pyo3::PyType> = _pyo3::Py::from_borrowed_ptr(
py, cls as *mut _pyo3::ffi::PyObject);
#cls::#fname(&cls, #(#names),*)
}}
}
fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
if spec.args.is_empty() {
return body
}
let mut params = Vec::new();
for arg in spec.args.iter() {
@ -223,9 +214,9 @@ fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
];
let mut output = [#(#placeholders),*];
match _pyo3::argparse::parse_args(
py, Some(LOCATION), PARAMS, &args,
kwargs.as_ref(), #accept_args, #accept_kwargs, &mut output) {
match _pyo3::argparse::parse_args(py, Some(LOCATION), PARAMS, &args,
kwargs.as_ref(), #accept_args, #accept_kwargs,
&mut output) {
Ok(_) => {
let mut _iter = output.iter();
@ -246,7 +237,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.as_object())
match <#ty as _pyo3::FromPyObject>::extract(&args)
{
Ok(#name) => {
#body
@ -262,7 +253,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
}
}
else {
if let Some(ref opt_ty) = arg.optional {
if let Some(_) = arg.optional {
// default value
let mut default = Tokens::new();
if let Some(d) = spec.default_value(name) {
@ -273,19 +264,21 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
}
quote! {
match match _iter.next().unwrap().as_ref() {
Some(obj) => {
if obj == &py.None() {
Ok(#default)
} else {
match <#opt_ty as _pyo3::FromPyObject>::extract(py, obj) {
Ok(obj) => Ok(Some(obj)),
Err(e) => Err(e)
match
match _iter.next().unwrap().as_ref() {
Some(obj) => {
if obj == &py.None() {
Ok(#default)
} else {
match _pyo3::callback::unref_r(obj).extract() {
Ok(obj) => Ok(Some(obj)),
Err(e) => Err(e)
}
}
}
},
None => Ok(#default)
} {
},
None => Ok(#default)
}
{
Ok(#name) => #body,
Err(e) => Err(e)
}
@ -297,7 +290,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
if obj == &py.None() {
Ok(#default)
} else {
match <#ty as _pyo3::FromPyObject>::extract(py, obj) {
match _pyo3::callback::unref_r(obj).extract() {
Ok(obj) => Ok(obj),
Err(e) => Err(e),
}
@ -312,8 +305,8 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
}
else {
quote! {
match <#ty as _pyo3::FromPyObject>::extract(
py, _iter.next().unwrap().as_ref().unwrap())
match _pyo3::callback::unref_r(
_iter.next().unwrap().as_ref().unwrap()).extract()
{
Ok(#name) => {
#body

View File

@ -20,9 +20,9 @@ static DEFAULT_METHODS: Methods = Methods {
pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
match ast.node {
syn::ItemKind::Impl(_, _, _, ref path, ref ty, ref mut impl_items) => {
if let &Some(ref path) = path {
if let Some(segment) = path.segments.last() {
syn::ItemKind::Impl(_, _, ref mut gen, ref mut path, ref ty, ref mut impl_items) => {
if let &mut Some(ref mut path) = path {
let tokens = if let Some(ref mut segment) = path.segments.last() {
match segment.ident.as_ref() {
"PyObjectProtocol" =>
impl_proto_impl(ty, impl_items, &defs::OBJECT),
@ -48,12 +48,28 @@ pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
path.clone(), ty, impl_items, &DEFAULT_METHODS),
_ => {
warn!("#[proto] can not be used with this block");
Tokens::new()
return Tokens::new()
}
}
} else {
panic!("#[proto] can only be used with protocol trait implementations")
}
};
// attach lifetime
gen.lifetimes = vec![syn::LifetimeDef {
attrs: vec![], bounds: vec![],
lifetime: syn::Lifetime { ident: syn::Ident::from("\'p") },
}];
let seg = path.segments.pop().unwrap();
path.segments.push(syn::PathSegment{
ident: seg.ident.clone(),
parameters: syn::PathParameters::AngleBracketed(
syn::AngleBracketedParameterData {
lifetimes: vec![syn::Lifetime { ident: syn::Ident::from("\'p") }],
types: vec![], bindings: vec![] })});
tokens
} else {
panic!("#[proto] can only be used with protocol trait implementations")
}
@ -81,7 +97,7 @@ fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &de
let fn_spec = FnSpec::parse(
&iimpl.ident, sig, &mut iimpl.attrs);
let meth = py_method::impl_wrap(ty, &iimpl.ident, &fn_spec);
let meth = py_method::impl_proto_wrap(ty, &iimpl.ident, &fn_spec);
py_methods.push(
quote! {

View File

@ -7,7 +7,7 @@ use libc;
use pyptr::Py;
use python::{Python, IntoPythonPointer};
use objects::exc;
use conversion::ToPyObject;
use conversion::IntoPyObject;
use ffi::{self, Py_hash_t};
use err::{PyErr, PyResult};
@ -22,7 +22,7 @@ pub trait CallbackConverter<S> {
pub struct PyObjectCallbackConverter;
impl <S> CallbackConverter<S> for PyObjectCallbackConverter
where S: ToPyObject
where S: IntoPyObject
{
type R = *mut ffi::PyObject;
@ -94,7 +94,7 @@ pub struct IterNextResultConverter;
impl <T> CallbackConverter<Option<T>>
for IterNextResultConverter
where T: ToPyObject
where T: IntoPyObject
{
type R = *mut ffi::PyObject;
@ -167,6 +167,9 @@ impl <T> CallbackConverter<T> for HashConverter
pub unsafe fn unref<'p, T>(p: Py<'p, T>) -> &Py<T> {
{&p as *const _}.as_ref().unwrap()
}
pub unsafe fn unref_r<'p, T>(p: &'p Py<'p, T>) -> &'p Py<T> {
{p as *const _}.as_ref().unwrap()
}
pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python<'p>) -> PyResult<T>,
@ -197,6 +200,35 @@ pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
ret
}
pub unsafe fn handle_cb<F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python) -> PyResult<T>,
F: panic::UnwindSafe,
C: CallbackConverter<T>
{
let guard = AbortOnDrop(location);
let ret = panic::catch_unwind(|| {
let py = Python::assume_gil_acquired();
match f(py) {
Ok(val) => {
C::convert(val, py)
}
Err(e) => {
e.restore(py);
C::error_value()
}
}
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
handle_panic(Python::assume_gil_acquired(), err);
C::error_value()
}
};
mem::forget(guard);
ret
}
fn handle_panic(_py: Python, _panic: &any::Any) {
unsafe {
ffi::PyErr_SetString(ffi::PyExc_SystemError, "Rust panic\0".as_ptr() as *const i8);

View File

@ -26,74 +26,74 @@ use class::methods::PyMethodDef;
/// Object customization
#[allow(unused_variables)]
pub trait PyObjectProtocol<'a>: PyTypeInfo + Sized + 'static {
pub trait PyObjectProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __getattr__(&self, name: Self::Name)
-> Self::Result where Self: PyObjectGetAttrProtocol<'a> {unimplemented!()}
-> Self::Result where Self: PyObjectGetAttrProtocol<'p> {unimplemented!()}
fn __setattr__(&self, name: Self::Name, value: Self::Value)
-> Self::Result where Self: PyObjectSetAttrProtocol<'a> {unimplemented!()}
-> Self::Result where Self: PyObjectSetAttrProtocol<'p> {unimplemented!()}
fn __delattr__(&self, name: Self::Name)
-> Self::Result where Self: PyObjectDelAttrProtocol<'a> {unimplemented!()}
-> Self::Result where Self: PyObjectDelAttrProtocol<'p> {unimplemented!()}
fn __str__(&self) -> Self::Result where Self: PyObjectStrProtocol<'a> {unimplemented!()}
fn __str__(&self) -> Self::Result where Self: PyObjectStrProtocol<'p> {unimplemented!()}
fn __repr__(&self) -> Self::Result where Self: PyObjectReprProtocol<'a> {unimplemented!()}
fn __repr__(&self) -> Self::Result where Self: PyObjectReprProtocol<'p> {unimplemented!()}
fn __format__(&self, format_spec: Self::Format)
-> Self::Result where Self: PyObjectFormatProtocol<'a> {unimplemented!()}
-> Self::Result where Self: PyObjectFormatProtocol<'p> {unimplemented!()}
fn __hash__(&self) -> Self::Result where Self: PyObjectHashProtocol<'a> {unimplemented!()}
fn __hash__(&self) -> Self::Result where Self: PyObjectHashProtocol<'p> {unimplemented!()}
fn __bool__(&self) -> Self::Result where Self: PyObjectBoolProtocol<'a> {unimplemented!()}
fn __bool__(&self) -> Self::Result where Self: PyObjectBoolProtocol<'p> {unimplemented!()}
fn __bytes__(&self) -> Self::Result where Self: PyObjectBytesProtocol<'a> {unimplemented!()}
fn __bytes__(&self) -> Self::Result where Self: PyObjectBytesProtocol<'p> {unimplemented!()}
fn __richcmp__(&self, other: Self::Other, op: CompareOp)
-> Self::Result where Self: PyObjectRichcmpProtocol<'a> {unimplemented!()}
-> Self::Result where Self: PyObjectRichcmpProtocol<'p> {unimplemented!()}
}
pub trait PyObjectGetAttrProtocol<'a>: PyObjectProtocol<'a> {
type Name: FromPyObject<'a>;
pub trait PyObjectGetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyObjectSetAttrProtocol<'a>: PyObjectProtocol<'a> {
type Name: FromPyObject<'a>;
type Value: FromPyObject<'a>;
pub trait PyObjectSetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Value: FromPyObject<'p>;
type Result: Into<PyResult<()>>;
}
pub trait PyObjectDelAttrProtocol<'a>: PyObjectProtocol<'a> {
type Name: FromPyObject<'a>;
pub trait PyObjectDelAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Result: Into<PyResult<()>>;
}
pub trait PyObjectStrProtocol<'a>: PyObjectProtocol<'a> {
pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyObjectReprProtocol<'a>: PyObjectProtocol<'a> {
pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyObjectFormatProtocol<'a>: PyObjectProtocol<'a> {
type Format: FromPyObject<'a>;
pub trait PyObjectFormatProtocol<'p>: PyObjectProtocol<'p> {
type Format: FromPyObject<'p>;
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyObjectHashProtocol<'a>: PyObjectProtocol<'a> {
pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
type Result: Into<PyResult<usize>>;
}
pub trait PyObjectBoolProtocol<'a>: PyObjectProtocol<'a> {
pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
type Result: Into<PyResult<bool>>;
}
pub trait PyObjectBytesProtocol<'a>: PyObjectProtocol<'a> {
pub trait PyObjectBytesProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyObjectRichcmpProtocol<'a>: PyObjectProtocol<'a> {
type Other: FromPyObject<'a>;
pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
type Other: FromPyObject<'p>;
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
@ -117,7 +117,7 @@ impl<T> PyObjectProtocolImpl for T {
}
}
impl<'a, T> PyObjectProtocolImpl for T where T: PyObjectProtocol<'a> {
impl<'p, T> PyObjectProtocolImpl for T where T: PyObjectProtocol<'p> {
#[inline]
fn methods() -> Vec<PyMethodDef> {
let mut methods = Vec::new();
@ -151,14 +151,14 @@ impl<'a, T> PyObjectProtocolImpl for T where T: PyObjectProtocol<'a> {
trait PyObjectGetAttrProtocolImpl {
fn tp_getattro() -> Option<ffi::binaryfunc>;
}
impl<'a, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_getattro() -> Option<ffi::binaryfunc> {
None
}
}
impl<'a, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'a>
impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'p>
{
#[inline]
fn tp_getattro() -> Option<ffi::binaryfunc> {
@ -171,21 +171,21 @@ trait PyObjectSetAttrProtocolImpl {
fn tp_setattro() -> Option<ffi::setattrofunc>;
}
impl<'a, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_setattro() -> Option<ffi::setattrofunc> {
None
}
}
impl<'a, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'a>
impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'p>
{
#[inline]
fn tp_setattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'a>
where T: PyObjectSetAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__setattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -218,21 +218,21 @@ impl<'a, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'
trait PyObjectDelAttrProtocolImpl {
fn tp_delattro() -> Option<ffi::setattrofunc>;
}
impl<'a, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> {
None
}
}
impl<'a, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'a>
impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'p>
{
#[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectDelAttrProtocol<'a>
where T: PyObjectDelAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -257,15 +257,15 @@ impl<'a, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'
}
impl<'a, T> PyObjectDelAttrProtocolImpl for T
where T: PyObjectSetAttrProtocol<'a> + PyObjectDelAttrProtocol<'a>
impl<'p, T> PyObjectDelAttrProtocolImpl for T
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
{
#[inline]
fn tp_delattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'a> + PyObjectDelAttrProtocol<'a>
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -301,14 +301,14 @@ impl<'a, T> PyObjectDelAttrProtocolImpl for T
trait PyObjectStrProtocolImpl {
fn tp_str() -> Option<ffi::unaryfunc>;
}
impl<'a, T> PyObjectStrProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_str() -> Option<ffi::unaryfunc> {
None
}
}
impl<'a, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'a>
impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'p>
{
#[inline]
fn tp_str() -> Option<ffi::unaryfunc> {
@ -319,14 +319,14 @@ impl<'a, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'a>
trait PyObjectReprProtocolImpl {
fn tp_repr() -> Option<ffi::unaryfunc>;
}
impl<'a, T> PyObjectReprProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_repr() -> Option<ffi::unaryfunc> {
None
}
}
impl<'a, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'a>
impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'p>
{
#[inline]
fn tp_repr() -> Option<ffi::unaryfunc> {
@ -338,7 +338,7 @@ impl<'a, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'a>
pub trait PyObjectFormatProtocolImpl {
fn __format__() -> Option<PyMethodDef>;
}
impl<'a, T> PyObjectFormatProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectFormatProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn __format__() -> Option<PyMethodDef> {
@ -350,7 +350,7 @@ impl<'a, T> PyObjectFormatProtocolImpl for T where T: PyObjectProtocol<'a>
pub trait PyObjectBytesProtocolImpl {
fn __bytes__() -> Option<PyMethodDef>;
}
impl<'a, T> PyObjectBytesProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectBytesProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn __bytes__() -> Option<PyMethodDef> {
@ -362,14 +362,14 @@ impl<'a, T> PyObjectBytesProtocolImpl for T where T: PyObjectProtocol<'a>
trait PyObjectHashProtocolImpl {
fn tp_hash() -> Option<ffi::hashfunc>;
}
impl<'a, T> PyObjectHashProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_hash() -> Option<ffi::hashfunc> {
None
}
}
impl<'a, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'a>
impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'p>
{
#[inline]
fn tp_hash() -> Option<ffi::hashfunc> {
@ -380,14 +380,14 @@ impl<'a, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'a>
trait PyObjectBoolProtocolImpl {
fn nb_bool() -> Option<ffi::inquiry>;
}
impl<'a, T> PyObjectBoolProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn nb_bool() -> Option<ffi::inquiry> {
None
}
}
impl<'a, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'a>
impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'p>
{
#[inline]
fn nb_bool() -> Option<ffi::inquiry> {
@ -398,21 +398,21 @@ impl<'a, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'a>
trait PyObjectRichcmpProtocolImpl {
fn tp_richcompare() -> Option<ffi::richcmpfunc>;
}
impl<'a, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectProtocol<'a>
impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectProtocol<'p>
{
#[inline]
default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
None
}
}
impl<'a, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'a>
impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'p>
{
#[inline]
fn tp_richcompare() -> Option<ffi::richcmpfunc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject
where T: PyObjectRichcmpProtocol<'a>
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject
where T: PyObjectRichcmpProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()");
::callback::handle(LOCATION, PyObjectCallbackConverter, |py| {

View File

@ -9,20 +9,18 @@ use std::os::raw::c_int;
use ffi;
use err::PyResult;
use python::{Python, PythonObject};
use objects::PyObject;
use callback::{handle_callback, UnitCallbackConverter};
use typeob::PyTypeInfo;
use callback::{handle, UnitCallbackConverter};
use class::NO_METHODS;
/// Buffer protocol interface
pub trait PyBufferProtocol {
pub trait PyBufferProtocol<'p> : PyTypeInfo {
fn bf_getbuffer(&self, py: Python, view: *mut ffi::Py_buffer, flags: c_int)
-> PyResult<()>;
fn bf_getbuffer(&self, view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()>;
fn bf_releasebuffer(&self, py: Python, view: *mut ffi::Py_buffer)
-> PyResult<()>;
fn bf_releasebuffer(&self, view: *mut ffi::Py_buffer) -> PyResult<()>;
}
#[doc(hidden)]
@ -36,14 +34,12 @@ impl<T> PyBufferProtocolImpl for T {
}
}
impl<T> PyBufferProtocol for T {
impl<'p, T> PyBufferProtocol<'p> for T where T: PyTypeInfo {
default fn bf_getbuffer(&self, _py: Python,
_view: *mut ffi::Py_buffer, _flags: c_int) -> PyResult<()> {
default fn bf_getbuffer(&self, _view: *mut ffi::Py_buffer, _flags: c_int) -> PyResult<()> {
Ok(())
}
default fn bf_releasebuffer(&self, _py: Python,
_view: *mut ffi::Py_buffer) -> PyResult<()> {
default fn bf_releasebuffer(&self, _view: *mut ffi::Py_buffer) -> PyResult<()> {
Ok(())
}
}
@ -52,8 +48,8 @@ impl<T> PyBufferProtocol for T {
impl ffi::PyBufferProcs {
/// Construct PyBufferProcs struct for PyTypeObject.tp_as_buffer
pub fn new<T>() -> Option<ffi::PyBufferProcs>
where T: PyBufferProtocol + PyBufferProtocolImpl + PythonObject
pub fn new<'p, T>() -> Option<ffi::PyBufferProcs>
where T: PyBufferProtocol<'p> + PyBufferProtocolImpl
{
let methods = T::methods();
if methods.is_empty() {
@ -66,18 +62,16 @@ impl ffi::PyBufferProcs {
match name {
&"bf_getbuffer" => {
buf_procs.bf_getbuffer = {
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer, arg2: c_int) -> c_int
where T: PyBufferProtocol + PythonObject
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
arg1: *mut ffi::Py_buffer,
arg2: c_int) -> c_int
where T: PyBufferProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::<PyBufferProtocol>()");
handle_callback(LOCATION, UnitCallbackConverter,
|py| {
let slf = PyObject::from_borrowed_ptr(py, slf).unchecked_cast_into::<T>();
let result = slf.bf_getbuffer(py, arg1, arg2);
::PyDrop::release_ref(slf, py);
result
}
)
handle(LOCATION, UnitCallbackConverter, |py| {
let slf = PyObject::from_borrowed_ptr(py, slf);
slf.bf_getbuffer(arg1, arg2)
})
}
Some(wrap::<T>)
}

View File

@ -5,33 +5,33 @@
//!
use err::PyResult;
use python::{Python, PythonObject};
use typeob::PyTypeInfo;
use class::methods::PyMethodDef;
/// Context manager interface
#[allow(unused_variables)]
pub trait PyContextProtocol: PythonObject {
pub trait PyContextProtocol<'p>: PyTypeInfo {
fn __enter__(&self, py: Python)
-> Self::Result where Self: PyContextEnterProtocol { unimplemented!() }
fn __enter__(&mut self)
-> Self::Result where Self: PyContextEnterProtocol<'p> {unimplemented!()}
fn __exit__(&self, py: Python,
fn __exit__(&mut self,
exc_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>)
-> Self::Result where Self: PyContextExitProtocol { unimplemented!() }
-> Self::Result where Self: PyContextExitProtocol<'p> { unimplemented!() }
}
pub trait PyContextEnterProtocol: PyContextProtocol {
pub trait PyContextEnterProtocol<'p>: PyContextProtocol<'p> {
type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyContextExitProtocol: PyContextProtocol {
type ExcType: for<'a> ::FromPyObject<'a>;
type ExcValue: for<'a> ::FromPyObject<'a>;
type Traceback: for<'a> ::FromPyObject<'a>;
pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
type ExcType: ::FromPyObject<'p>;
type ExcValue: ::FromPyObject<'p>;
type Traceback: ::FromPyObject<'p>;
type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
@ -48,7 +48,7 @@ impl<T> PyContextProtocolImpl for T {
}
}
impl<T> PyContextProtocolImpl for T where T: PyContextProtocol {
impl<'p, T> PyContextProtocolImpl for T where T: PyContextProtocol<'p> {
#[inline]
fn methods() -> Vec<PyMethodDef> {
let mut methods = Vec::new();
@ -69,8 +69,7 @@ pub trait PyContextEnterProtocolImpl {
fn __enter__() -> Option<PyMethodDef>;
}
impl<T> PyContextEnterProtocolImpl for T
where T: PyContextProtocol
impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p>
{
#[inline]
default fn __enter__() -> Option<PyMethodDef> {
@ -83,8 +82,7 @@ pub trait PyContextExitProtocolImpl {
fn __exit__() -> Option<PyMethodDef>;
}
impl<T> PyContextExitProtocolImpl for T
where T: PyContextProtocol
impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p>
{
#[inline]
default fn __exit__() -> Option<PyMethodDef> {

View File

@ -8,27 +8,25 @@
use ffi;
use err::PyResult;
use python::{Python, PythonObject};
use typeob::PyTypeInfo;
use callback::PyObjectCallbackConverter;
/// Iterator protocol
#[allow(unused_variables)]
pub trait PyIterProtocol : PythonObject {
fn __iter__(&self, py: Python)
-> Self::Result where Self: PyIterIterProtocol { unimplemented!() }
pub trait PyIterProtocol<'p> : PyTypeInfo {
fn __iter__(&self) -> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
fn __next__(&self, py: Python)
-> Self::Result where Self: PyIterNextProtocol { unimplemented!() }
fn __next__(&self) -> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
}
pub trait PyIterIterProtocol: PyIterProtocol {
pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PyIterNextProtocol: PyIterProtocol {
pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
@ -44,7 +42,7 @@ impl<T> PyIterProtocolImpl for T {
default fn tp_as_iter(_: &mut ffi::PyTypeObject) {}
}
impl<T> PyIterProtocolImpl for T where T: PyIterProtocol {
impl<'p, T> PyIterProtocolImpl for T where T: PyIterProtocol<'p> {
#[inline]
fn tp_as_iter(typeob: &mut ffi::PyTypeObject) {
typeob.tp_iter = Self::tp_iter();
@ -56,8 +54,7 @@ trait PyIterIterProtocolImpl {
fn tp_iter() -> Option<ffi::getiterfunc>;
}
impl<T> PyIterIterProtocolImpl for T
where T: PyIterProtocol
impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p>
{
#[inline]
default fn tp_iter() -> Option<ffi::getiterfunc> {
@ -65,12 +62,11 @@ impl<T> PyIterIterProtocolImpl for T
}
}
impl<T> PyIterIterProtocolImpl for T
where T: PyIterIterProtocol
impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterIterProtocol<'p>
{
#[inline]
fn tp_iter() -> Option<ffi::getiterfunc> {
py_unary_func_!(PyIterIterProtocol, T::__iter__, PyObjectCallbackConverter)
py_unary_func!(PyIterIterProtocol, T::__iter__, PyObjectCallbackConverter)
}
}
@ -78,8 +74,8 @@ trait PyIterNextProtocolImpl {
fn tp_iternext() -> Option<ffi::iternextfunc>;
}
impl<T> PyIterNextProtocolImpl for T
where T: PyIterProtocol
impl<'p, T> PyIterNextProtocolImpl for T
where T: PyIterProtocol<'p>
{
#[inline]
default fn tp_iternext() -> Option<ffi::iternextfunc> {
@ -87,11 +83,11 @@ impl<T> PyIterNextProtocolImpl for T
}
}
impl<T> PyIterNextProtocolImpl for T
where T: PyIterNextProtocol
impl<'p, T> PyIterNextProtocolImpl for T
where T: PyIterNextProtocol<'p>
{
#[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> {
py_unary_func_!(PyIterNextProtocol, T::__next__, PyObjectCallbackConverter)
py_unary_func!(PyIterNextProtocol, T::__next__, PyObjectCallbackConverter)
}
}

View File

@ -4,21 +4,21 @@
pub mod async;
pub mod basic;
//pub mod buffer;
//pub mod context;
pub mod buffer;
pub mod context;
pub mod descr;
pub mod mapping;
pub mod methods;
pub mod number;
//pub mod iter;
pub mod iter;
pub mod gc;
pub mod sequence;
pub use self::basic::PyObjectProtocol;
pub use self::async::PyAsyncProtocol;
//pub use self::iter::PyIterProtocol;
//pub use self::buffer::PyBufferProtocol;
//pub use self::context::PyContextProtocol;
pub use self::iter::PyIterProtocol;
pub use self::buffer::PyBufferProtocol;
pub use self::context::PyContextProtocol;
pub use self::descr::PyDescrProtocol;
pub use self::number::PyNumberProtocol;
pub use self::mapping::PyMappingProtocol;

View File

@ -17,78 +17,78 @@ use conversion::{ToPyObject, FromPyObject};
/// Sequece interface
#[allow(unused_variables)]
pub trait PySequenceProtocol<'a>: PyTypeInfo + Sized + 'static {
pub trait PySequenceProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __len__(&self) -> Self::Result
where Self: PySequenceLenProtocol<'a> { unimplemented!() }
where Self: PySequenceLenProtocol<'p> { unimplemented!() }
fn __getitem__(&self, key: isize) -> Self::Result
where Self: PySequenceGetItemProtocol<'a> { unimplemented!() }
where Self: PySequenceGetItemProtocol<'p> { unimplemented!() }
fn __setitem__(&self, key: isize, value: Self::Value) -> Self::Result
where Self: PySequenceSetItemProtocol<'a> { unimplemented!() }
where Self: PySequenceSetItemProtocol<'p> { unimplemented!() }
fn __delitem__(&self, key: isize) -> Self::Result
where Self: PySequenceDelItemProtocol<'a> { unimplemented!() }
where Self: PySequenceDelItemProtocol<'p> { unimplemented!() }
fn __contains__(&self, item: Self::Item) -> Self::Result
where Self: PySequenceContainsProtocol<'a> { unimplemented!() }
where Self: PySequenceContainsProtocol<'p> { unimplemented!() }
fn __concat__(&self, other: Self::Other) -> Self::Result
where Self: PySequenceConcatProtocol<'a> { unimplemented!() }
where Self: PySequenceConcatProtocol<'p> { unimplemented!() }
fn __repeat__(&self, count: isize) -> Self::Result
where Self: PySequenceRepeatProtocol<'a> { unimplemented!() }
where Self: PySequenceRepeatProtocol<'p> { unimplemented!() }
fn __inplace_concat__(&self, other: Self::Other) -> Self::Result
where Self: PySequenceInplaceConcatProtocol<'a> { unimplemented!() }
where Self: PySequenceInplaceConcatProtocol<'p> { unimplemented!() }
fn __inplace_repeat__(&self, count: isize) -> Self::Result
where Self: PySequenceInplaceRepeatProtocol<'a> { unimplemented!() }
where Self: PySequenceInplaceRepeatProtocol<'p> { unimplemented!() }
}
// The following are a bunch of marker traits used to detect
// the existance of a slotted method.
pub trait PySequenceLenProtocol<'a>: PySequenceProtocol<'a> {
pub trait PySequenceLenProtocol<'p>: PySequenceProtocol<'p> {
type Result: Into<PyResult<usize>>;
}
pub trait PySequenceGetItemProtocol<'a>: PySequenceProtocol<'a> {
pub trait PySequenceGetItemProtocol<'p>: PySequenceProtocol<'p> {
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PySequenceSetItemProtocol<'a>: PySequenceProtocol<'a> {
type Value: FromPyObject<'a>;
pub trait PySequenceSetItemProtocol<'p>: PySequenceProtocol<'p> {
type Value: FromPyObject<'p>;
type Result: Into<PyResult<()>>;
}
pub trait PySequenceDelItemProtocol<'a>: PySequenceProtocol<'a> {
pub trait PySequenceDelItemProtocol<'p>: PySequenceProtocol<'p> {
type Result: Into<PyResult<()>>;
}
pub trait PySequenceContainsProtocol<'a>: PySequenceProtocol<'a> {
type Item: FromPyObject<'a>;
pub trait PySequenceContainsProtocol<'p>: PySequenceProtocol<'p> {
type Item: FromPyObject<'p>;
type Result: Into<PyResult<bool>>;
}
pub trait PySequenceConcatProtocol<'a>: PySequenceProtocol<'a> {
type Other: FromPyObject<'a>;
pub trait PySequenceConcatProtocol<'p>: PySequenceProtocol<'p> {
type Other: FromPyObject<'p>;
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PySequenceRepeatProtocol<'a>: PySequenceProtocol<'a> {
pub trait PySequenceRepeatProtocol<'p>: PySequenceProtocol<'p> {
type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>;
}
pub trait PySequenceInplaceConcatProtocol<'a>: PySequenceProtocol<'a> + ToPyObject {
type Other: FromPyObject<'a>;
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + ToPyObject {
type Other: FromPyObject<'p>;
type Result: Into<PyResult<Self>>;
}
pub trait PySequenceInplaceRepeatProtocol<'a>: PySequenceProtocol<'a> + ToPyObject {
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + ToPyObject {
type Result: Into<PyResult<Self>>;
}
@ -104,7 +104,7 @@ impl<T> PySequenceProtocolImpl for T {
}
}
impl<'a, T> PySequenceProtocolImpl for T where T: PySequenceProtocol<'a> {
impl<'p, T> PySequenceProtocolImpl for T where T: PySequenceProtocol<'p> {
#[inline]
fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
let f = if let Some(df) = Self::sq_del_item() {
@ -133,7 +133,7 @@ trait PySequenceLenProtocolImpl {
fn sq_length() -> Option<ffi::lenfunc>;
}
impl<'a, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_length() -> Option<ffi::lenfunc> {
@ -141,7 +141,7 @@ impl<'a, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceLenProtocolImpl for T where T: PySequenceLenProtocol<'a>
impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceLenProtocol<'p>
{
#[inline]
fn sq_length() -> Option<ffi::lenfunc> {
@ -153,7 +153,7 @@ trait PySequenceGetItemProtocolImpl {
fn sq_item() -> Option<ffi::ssizeargfunc>;
}
impl<'a, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_item() -> Option<ffi::ssizeargfunc> {
@ -161,7 +161,7 @@ impl<'a, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceGetItemProtocolImpl for T where T: PySequenceGetItemProtocol<'a>
impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceGetItemProtocol<'p>
{
#[inline]
fn sq_item() -> Option<ffi::ssizeargfunc> {
@ -173,7 +173,7 @@ trait PySequenceSetItemProtocolImpl {
fn sq_ass_item() -> Option<ffi::ssizeobjargproc>;
}
impl<'a, T> PySequenceSetItemProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceSetItemProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
@ -181,14 +181,14 @@ impl<'a, T> PySequenceSetItemProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceSetItemProtocolImpl for T where T: PySequenceSetItemProtocol<'a>
impl<'p, T> PySequenceSetItemProtocolImpl for T where T: PySequenceSetItemProtocol<'p>
{
#[inline]
fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'a>
where T: PySequenceSetItemProtocol<'p>
{
const LOCATION: &'static str = "foo.__setitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -215,7 +215,7 @@ impl<'a, T> PySequenceSetItemProtocolImpl for T where T: PySequenceSetItemProtoc
trait PySequenceDelItemProtocolImpl {
fn sq_del_item() -> Option<ffi::ssizeobjargproc>;
}
impl<'a, T> PySequenceDelItemProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
@ -223,14 +223,14 @@ impl<'a, T> PySequenceDelItemProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceDelItemProtocolImpl for T where T: PySequenceDelItemProtocol<'a>
impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceDelItemProtocol<'p>
{
#[inline]
default fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceDelItemProtocol<'a>
where T: PySequenceDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__detitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -248,15 +248,15 @@ impl<'a, T> PySequenceDelItemProtocolImpl for T where T: PySequenceDelItemProtoc
}
}
impl<'a, T> PySequenceDelItemProtocolImpl for T
where T: PySequenceSetItemProtocol<'a> + PySequenceDelItemProtocol<'a>
impl<'p, T> PySequenceDelItemProtocolImpl for T
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p>
{
#[inline]
fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'a> + PySequenceDelItemProtocol<'a>
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__set/del_item__()";
@ -285,7 +285,7 @@ trait PySequenceContainsProtocolImpl {
fn sq_contains() -> Option<ffi::objobjproc>;
}
impl<'a, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_contains() -> Option<ffi::objobjproc> {
@ -293,13 +293,13 @@ impl<'a, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceContainsProtocolImpl for T where T: PySequenceContainsProtocol<'a>
impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceContainsProtocol<'p>
{
#[inline]
fn sq_contains() -> Option<ffi::objobjproc> {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject) -> c_int
where T: PySequenceContainsProtocol<'a>
where T: PySequenceContainsProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".__contains__()");
::callback::handle(LOCATION, BoolCallbackConverter, |py| {
@ -321,7 +321,7 @@ trait PySequenceConcatProtocolImpl {
fn sq_concat() -> Option<ffi::binaryfunc>;
}
impl<'a, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_concat() -> Option<ffi::binaryfunc> {
@ -329,7 +329,7 @@ impl<'a, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'a>
}
}
impl<'a, T> PySequenceConcatProtocolImpl for T where T: PySequenceConcatProtocol<'a>
impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceConcatProtocol<'p>
{
#[inline]
fn sq_concat() -> Option<ffi::binaryfunc> {
@ -341,8 +341,8 @@ trait PySequenceRepeatProtocolImpl {
fn sq_repeat() -> Option<ffi::ssizeargfunc>;
}
impl<'a, T> PySequenceRepeatProtocolImpl for T
where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceRepeatProtocolImpl for T
where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_repeat() -> Option<ffi::ssizeargfunc> {
@ -350,8 +350,8 @@ impl<'a, T> PySequenceRepeatProtocolImpl for T
}
}
impl<'a, T> PySequenceRepeatProtocolImpl for T
where T: PySequenceRepeatProtocol<'a>
impl<'p, T> PySequenceRepeatProtocolImpl for T
where T: PySequenceRepeatProtocol<'p>
{
#[inline]
fn sq_repeat() -> Option<ffi::ssizeargfunc> {
@ -363,7 +363,7 @@ trait PySequenceInplaceConcatProtocolImpl {
fn sq_inplace_concat() -> Option<ffi::binaryfunc>;
}
impl<'a, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
@ -371,8 +371,8 @@ impl<'a, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtoco
}
}
impl<'a, T> PySequenceInplaceConcatProtocolImpl for T
where T: PySequenceInplaceConcatProtocol<'a>
impl<'p, T> PySequenceInplaceConcatProtocolImpl for T
where T: PySequenceInplaceConcatProtocol<'p>
{
#[inline]
fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
@ -385,7 +385,7 @@ trait PySequenceInplaceRepeatProtocolImpl {
fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc>;
}
impl<'a, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'a>
impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p>
{
#[inline]
default fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
@ -393,8 +393,8 @@ impl<'a, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtoco
}
}
impl<'a, T> PySequenceInplaceRepeatProtocolImpl for T
where T: PySequenceInplaceRepeatProtocol<'a>
impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T
where T: PySequenceInplaceRepeatProtocol<'p>
{
#[inline]
fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {

View File

@ -12,14 +12,6 @@ pub trait ToPyObject {
/// Converts self into a Python object.
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject>;
/// Converts self into a Python object. (Consumes self)
#[inline]
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject>
where Self: Sized
{
self.to_object(py)
}
/// Converts self into a Python object and calls the specified closure
/// on the native FFI pointer underlying the Python object.
///
@ -32,26 +24,18 @@ pub trait ToPyObject {
let obj = self.to_object(py).into_object();
f(obj.as_ptr())
}
// FFI functions that accept a borrowed reference will use:
// input.with_borrowed_ptr(|obj| ffi::Call(obj)
// 1) input is &PyObject
// -> with_borrowed_ptr() just forwards to the closure
// 2) input is PyObject
// -> with_borrowed_ptr() just forwards to the closure
// 3) input is &str, int, ...
// -> to_py_object() allocates new Python object; FFI call happens; PyObject::drop() calls Py_DECREF()
// FFI functions that steal a reference will use:
// let input = try!(input.into_py_object()); ffi::Call(input.steal_ptr())
// 1) input is &PyObject
// -> into_py_object() calls Py_INCREF
// 2) input is PyObject
// -> into_py_object() is no-op
// 3) input is &str, int, ...
// -> into_py_object() allocates new Python object
}
pub trait IntoPyObject {
/// Converts self into a Python object. (Consumes self)
#[inline]
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject>
where Self: Sized;
}
/// Conversion trait that allows various objects to be converted into PyTuple object.
pub trait ToPyTuple {
@ -115,6 +99,16 @@ impl <'p, T: ?Sized> RefFromPyObject<'p> for T
}
}
// Default IntoPyObject implementation
impl <T> IntoPyObject for T where T: ToPyObject
{
#[inline]
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
{
self.to_object(py)
}
}
/// Identity conversion: allows using existing `PyObject` instances where
/// `T: ToPyObject` is expected.
// ToPyObject for references
@ -125,11 +119,6 @@ impl <'a, T: ?Sized> ToPyObject for &'a T where T: ToPyObject {
<T as ToPyObject>::to_object(*self, py)
}
#[inline]
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
<T as ToPyObject>::to_object(self, py)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
@ -148,6 +137,9 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
None => py.None()
}
}
}
impl <T> IntoPyObject for Option<T> where T: IntoPyObject {
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
match self {
@ -157,6 +149,7 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
}
}
/// `()` is converted to Python `None`.
impl ToPyObject for () {
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
@ -165,7 +158,7 @@ impl ToPyObject for () {
}
impl<'source, T> FromPyObject<'source> for Option<T> where T: FromPyObject<'source> {
impl <'source, T> FromPyObject<'source> for Option<T> where T: FromPyObject<'source> {
fn extract<S>(obj: &'source Py<'source, S>) -> PyResult<Self>
where S: PyTypeInfo
{

View File

@ -69,9 +69,9 @@ pub use pyptr::{Py, PyPtr};
pub use err::{PyErr, PyResult, PyDowncastError};
pub use objects::*;
pub use python::Python;
pub use python::{AsPy, Python};
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, ToPyTuple};
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, ToPyTuple};
pub use class::{CompareOp};
pub mod class;
pub use class::*;
@ -104,14 +104,14 @@ macro_rules! py_replace_expr {
($_t:tt $sub:expr) => {$sub};
}
mod python;
pub mod python;
mod err;
mod callback;
mod conversion;
mod objects;
mod objectprotocol;
mod pythonrun;
mod typeob;
pub mod callback;
pub mod typeob;
pub mod argparse;
pub mod function;
pub mod buffer;

View File

@ -6,8 +6,8 @@ use std::ops::Deref;
use std::convert::{AsRef, AsMut};
use ffi;
use ::ToPyObject;
use err::{PyErr, PyResult, PyDowncastError};
use conversion::{ToPyObject, IntoPyObject};
use python::{Python, ToPythonPointer, IntoPythonPointer};
use objects::PyObject;
use typeob::{PyTypeInfo, PyObjectAlloc};
@ -433,17 +433,13 @@ impl<'source, T> ::FromPyObject<'source> for Py<'source, T>
}
}
impl<'a, T> ToPyObject for Py<'a, T> {
impl <'a, T> ToPyObject for Py<'a, T> {
#[inline]
default fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
PyObject::from_owned_ptr(py, self.inner)
}
#[inline]
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
PyObject::from_borrowed_ptr(py, self.inner)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
@ -451,3 +447,21 @@ impl<'a, T> ToPyObject for Py<'a, T> {
f(self.inner)
}
}
impl <'a, T> IntoPyObject for Py<'a, T> {
#[inline]
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
PyObject::from_borrowed_ptr(py, self.inner)
}
}
/// PyObject implements the `==` operator using reference equality:
/// `obj1 == obj2` in rust is equivalent to `obj1 is obj2` in Python.
impl<'p, T> PartialEq for Py<'p, T> {
#[inline]
fn eq(&self, o: &Py<T>) -> bool {
self.as_ptr() == o.as_ptr()
}
}

View File

@ -171,10 +171,10 @@ impl<'p> Python<'p> {
/// Create new PyObject instance
#[inline]
pub fn init<T>(&'p self, value: T) -> PyResult<::Py<'p, T>>
pub fn init<T>(&'p self, value: T) -> Py<'p, T>
where T: PyTypeInfo + PyObjectAlloc<Type=T>
{
::Py::new(self, value)
Py::new(self, value).unwrap()
}
/// Gets the Python builtin value `None`.

View File

@ -200,14 +200,14 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
<T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object);
// number methods
/*if let Some(meth) = <T as class::number::PyNumberProtocolImpl>::tp_as_number() {
if let Some(meth) = <T as class::number::PyNumberProtocolImpl>::tp_as_number() {
static mut NB_METHODS: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
*(unsafe { &mut NB_METHODS }) = meth;
type_object.tp_as_number = unsafe { &mut NB_METHODS };
mem::forget(meth);
} else {
type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods;
}*/
}
// mapping methods
if let Some(meth) = <T as class::mapping::PyMappingProtocolImpl>::tp_as_mapping() {
@ -240,7 +240,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
}
// buffer protocol
/*if let Some(meth) = ffi::PyBufferProcs::new::<T>() {
if let Some(meth) = ffi::PyBufferProcs::new::<T>() {
static mut BUFFER_PROCS: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
*(unsafe { &mut BUFFER_PROCS }) = meth;
type_object.tp_as_buffer = unsafe { &mut BUFFER_PROCS };
@ -277,7 +277,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
// strange
mem::forget(props);
}*/
}
// register type object
unsafe {
@ -301,7 +301,6 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
r
}
/*
fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
Option<ffi::PyCFunctionWithKeywords>,
Vec<ffi::PyMethodDef>) {
@ -378,4 +377,4 @@ fn py_class_properties<T>() -> Vec<ffi::PyGetSetDef> {
}
defs.values().map(|i| i.clone()).collect()
}*/
}

View File

@ -13,7 +13,7 @@ use pyo3::ffi;
macro_rules! py_run {
($py:expr, $val:ident, $code:expr) => {{
let d = PyDict::new($py);
d.set_item($py, stringify!($val), &$val).unwrap();
d.set_item(stringify!($val), &$val).unwrap();
//$py.run($code, None, Some(&d)).map_err(|e| e.print($py)).expect($code);
$py.run($code, None, Some(&d)).expect($code);
}}
@ -45,7 +45,7 @@ fn empty_class() {
let py = gil.python();
let typeobj = py.get_type::<EmptyClass>();
// By default, don't allow creating instances from python.
assert!(typeobj.call(py, NoArgs, None).is_err());
assert!(typeobj.call(NoArgs, None).is_err());
py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
}
@ -58,11 +58,11 @@ fn empty_class_in_module() {
let gil = Python::acquire_gil();
let py = gil.python();
let module = PyModule::new(py, "test_module.nested").unwrap();
module.add_class::<EmptyClassInModule>(py).unwrap();
module.add_class::<EmptyClassInModule>().unwrap();
let ty = module.get(py, "EmptyClassInModule").unwrap();
assert_eq!(ty.getattr(py, "__name__").unwrap().extract::<String>(py).unwrap(), "EmptyClassInModule");
assert_eq!(ty.getattr(py, "__module__").unwrap().extract::<String>(py).unwrap(), "test_module.nested");
let ty = module.getattr("EmptyClassInModule").unwrap();
assert_eq!(ty.getattr("__name__").unwrap().extract::<String>().unwrap(), "EmptyClassInModule");
assert_eq!(ty.getattr("__module__").unwrap().extract::<String>().unwrap(), "test_module.nested");
}
#[py::class]
@ -71,8 +71,8 @@ struct EmptyClassWithNew { }
#[py::methods]
impl EmptyClassWithNew {
#[__new__]
fn __new__(_cls: &PyType, py: Python) -> PyResult<EmptyClassWithNew> {
EmptyClassWithNew::create_instance(py)
fn __new__(cls: &PyType) -> PyResult<EmptyClassWithNew> {
Ok(EmptyClassWithNew{})
}
}
@ -81,7 +81,7 @@ fn empty_class_with_new() {
let gil = Python::acquire_gil();
let py = gil.python();
let typeobj = py.get_type::<EmptyClassWithNew>();
assert!(typeobj.call(py, NoArgs, None).unwrap().cast_into::<EmptyClassWithNew>(py).is_ok());
assert!(typeobj.call(NoArgs, None).unwrap().cast_into::<EmptyClassWithNew>().is_ok());
}
#[py::class]
@ -91,8 +91,8 @@ struct NewWithOneArg {
#[py::methods]
impl NewWithOneArg {
#[new]
fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult<NewWithOneArg> {
NewWithOneArg::create_instance(py, arg)
fn __new__(_cls: &PyType, arg: i32) -> PyResult<NewWithOneArg> {
Ok(NewWithOneArg{_data: arg})
}
}
@ -101,8 +101,8 @@ fn new_with_one_arg() {
let gil = Python::acquire_gil();
let py = gil.python();
let typeobj = py.get_type::<NewWithOneArg>();
let obj = typeobj.call(py, (42,), None).unwrap().cast_into::<NewWithOneArg>(py).unwrap();
assert_eq!(*obj._data(py), 42);
let obj = typeobj.call((42,), None).unwrap().cast_into::<NewWithOneArg>().unwrap();
assert_eq!(obj._data, 42);
}
#[py::class]
@ -114,8 +114,8 @@ struct NewWithTwoArgs {
#[py::methods]
impl NewWithTwoArgs {
#[new]
fn __new__(_cls: &PyType, py: Python, arg1: i32, arg2: i32) -> PyResult<NewWithTwoArgs> {
NewWithTwoArgs::create_instance(py, arg1, arg2)
fn __new__(_cls: &PyType, arg1: i32, arg2: i32) -> PyResult<NewWithTwoArgs> {
Ok(NewWithTwoArgs{_data1: arg1, _data2: arg2})
}
}
@ -124,9 +124,9 @@ fn new_with_two_args() {
let gil = Python::acquire_gil();
let py = gil.python();
let typeobj = py.get_type::<NewWithTwoArgs>();
let obj = typeobj.call(py, (10, 20), None).unwrap().cast_into::<NewWithTwoArgs>(py).unwrap();
assert_eq!(*obj._data1(py), 10);
assert_eq!(*obj._data2(py), 20);
let obj = typeobj.call((10, 20), None).unwrap().cast_into::<NewWithTwoArgs>().unwrap();
assert_eq!(obj._data1, 10);
assert_eq!(obj._data2, 20);
}
struct TestDropCall {
@ -144,16 +144,16 @@ struct DataIsDropped {
member2: TestDropCall,
}
#[test]
//#[test]
fn data_is_dropped() {
let gil = Python::acquire_gil();
let py = gil.python();
let drop_called1 = Arc::new(AtomicBool::new(false));
let drop_called2 = Arc::new(AtomicBool::new(false));
let inst = DataIsDropped::create_instance(py,
TestDropCall { drop_called: drop_called1.clone() },
TestDropCall { drop_called: drop_called2.clone() });
let inst = DataIsDropped{
member1: TestDropCall { drop_called: drop_called1.clone() },
member2: TestDropCall { drop_called: drop_called2.clone() }}.into_object(py);
assert!(drop_called1.load(Ordering::Relaxed) == false);
assert!(drop_called2.load(Ordering::Relaxed) == false);
drop(inst);
@ -161,6 +161,7 @@ fn data_is_dropped() {
assert!(drop_called2.load(Ordering::Relaxed) == true);
}
#[py::class]
struct InstanceMethod {
member: i32,
@ -168,8 +169,8 @@ struct InstanceMethod {
#[py::methods]
impl InstanceMethod {
fn method(&self, py: Python) -> PyResult<i32> {
Ok(*self.member(py))
fn method(&self) -> PyResult<i32> {
Ok(self.member)
}
}
@ -178,10 +179,10 @@ fn instance_method() {
let gil = Python::acquire_gil();
let py = gil.python();
let obj = InstanceMethod::create_instance(py, 42).unwrap();
assert!(obj.method(py).unwrap() == 42);
let obj = py.init(InstanceMethod{member: 42});
assert!(obj.method().unwrap() == 42);
let d = PyDict::new(py);
d.set_item(py, "obj", obj).unwrap();
d.set_item("obj", obj).unwrap();
py.run("assert obj.method() == 42", None, Some(&d)).unwrap();
}
@ -191,8 +192,8 @@ struct InstanceMethodWithArgs {
}
#[py::methods]
impl InstanceMethodWithArgs {
fn method(&self, py: Python, multiplier: i32) -> PyResult<i32> {
Ok(*self.member(py) * multiplier)
fn method(&self, multiplier: i32) -> PyResult<i32> {
Ok(self.member * multiplier)
}
}
@ -201,14 +202,15 @@ fn instance_method_with_args() {
let gil = Python::acquire_gil();
let py = gil.python();
let obj = InstanceMethodWithArgs::create_instance(py, 7).unwrap();
assert!(obj.method(py, 6).unwrap() == 42);
let obj = py.init(InstanceMethodWithArgs{member: 7});
assert!(obj.method(6).unwrap() == 42);
let d = PyDict::new(py);
d.set_item(py, "obj", obj).unwrap();
d.set_item("obj", obj).unwrap();
py.run("assert obj.method(3) == 21", None, Some(&d)).unwrap();
py.run("assert obj.method(multiplier=6) == 42", None, Some(&d)).unwrap();
}
/*
#[py::class]
struct ClassMethod {}
#[py::methods]
@ -233,7 +235,7 @@ fn class_method() {
d.set_item(py, "C", py.get_type::<ClassMethod>()).unwrap();
py.run("assert C.method() == 'ClassMethod.method()!'", None, Some(&d)).unwrap();
py.run("assert C().method() == 'ClassMethod.method()!'", None, Some(&d)).unwrap();
}
}*/
//py_class!(class ClassMethodWithArgs |py| {
// @classmethod
@ -298,6 +300,7 @@ impl StaticMethod {
// py.run("assert C.method(1337) == '0x539'", None, Some(&d)).unwrap();
//}
#[py::class]
struct GCIntegration {
self_ref: RefCell<PyObject>,
@ -362,7 +365,6 @@ fn len() {
py_expect_exception!(py, inst, "len(inst)", OverflowError);
}
/*py_class!(class Iterator |py| {
data iter: RefCell<Box<iter::Iterator<Item=i32> + Send>>;
@ -385,21 +387,20 @@ fn iterator() {
py_assert!(py, inst, "list(inst) == [5, 6, 7]");
}*/
#[py::class]
struct StringMethods {}
#[py::proto]
impl PyObjectProtocol for StringMethods {
fn __str__(&self, py: Python) -> PyResult<&'static str> {
fn __str__(&self) -> PyResult<&'static str> {
Ok("str")
}
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
fn __repr__(&self) -> PyResult<&'static str> {
Ok("repr")
}
fn __format__(&self, py: Python, format_spec: String) -> PyResult<String> {
fn __format__(&self, format_spec: String) -> PyResult<String> {
Ok(format!("format({})", format_spec))
}
@ -407,7 +408,7 @@ impl PyObjectProtocol for StringMethods {
// Ok(PyString::new(py, "unicode"))
//}
fn __bytes__(&self, py: Python) -> PyResult<PyBytes> {
fn __bytes__(&self) -> PyResult<PyBytes> {
Ok(PyBytes::new(py, b"bytes"))
}
}
@ -432,11 +433,11 @@ struct Comparisons {
#[py::proto]
impl PyObjectProtocol for Comparisons {
fn __hash__(&self, py: Python) -> PyResult<usize> {
fn __hash__(&self) -> PyResult<usize> {
Ok(*self.val(py) as usize)
}
fn __bool__(&self, py: Python) -> PyResult<bool> {
fn __bool__(&self) -> PyResult<bool> {
Ok(*self.val(py) != 0)
}
}
@ -465,11 +466,11 @@ struct Sequence {}
#[py::proto]
impl PySequenceProtocol for Sequence {
fn __len__(&self, py: Python) -> PyResult<usize> {
fn __len__(&self) -> PyResult<usize> {
Ok(5)
}
fn __getitem__(&self, py: Python, key: isize) -> PyResult<isize> {
fn __getitem__(&self, key: isize) -> PyResult<isize> {
if key == 5 {
return Err(PyErr::new::<exc::IndexError, NoArgs>(py, NoArgs));
}
@ -495,7 +496,7 @@ struct Callable {}
impl Callable {
#[__call__]
fn __call__(&self, py: Python, arg: i32) -> PyResult<i32> {
fn __call__(&self, arg: i32) -> PyResult<i32> {
Ok(arg * 6)
}
}
@ -520,8 +521,8 @@ struct SetItem {
}
#[py::proto]
impl PyMappingProtocol for SetItem {
fn __setitem__(&self, py: Python, key: i32, val: i32) -> PyResult<()> {
impl PyMappingProtocol<'a> for SetItem {
fn __setitem__(&self, key: i32, val: i32) -> PyResult<()> {
*self.key_mut(py) = key;
*self.val_mut(py) = val;
Ok(())
@ -533,10 +534,10 @@ fn setitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let c = SetItem::create_instance(py, 0, 0).unwrap();
let c = SetItem::create_instance(0, 0).unwrap();
py_run!(py, c, "c[1] = 2");
assert_eq!(*c.key(py), 1);
assert_eq!(*c.val(py), 2);
assert_eq!(c.key, 1);
assert_eq!(c.val, 2);
py_expect_exception!(py, c, "del c[1]", NotImplementedError);
}
@ -546,8 +547,8 @@ struct DelItem {
}
#[py::proto]
impl PyMappingProtocol for DelItem {
fn __delitem__(&self, py: Python, key: i32) -> PyResult<()> {
impl PyMappingProtocol<'a> for DelItem {
fn __delitem__(&self, key: i32) -> PyResult<()> {
*self.key_mut(py) = key;
Ok(())
}
@ -571,12 +572,12 @@ struct SetDelItem {
#[py::proto]
impl PyMappingProtocol for SetDelItem {
fn __setitem__(&self, py: Python, key: i32, val: i32) -> PyResult<()> {
fn __setitem__(&self, key: i32, val: i32) -> PyResult<()> {
*self.val_mut(py) = Some(val);
Ok(())
}
fn __delitem__(&self, py: Python, key: i32) -> PyResult<()> {
fn __delitem__(&self, key: i32) -> PyResult<()> {
*self.val_mut(py) = None;
Ok(())
}
@ -599,7 +600,7 @@ struct Reversed {}
#[py::proto]
impl PyMappingProtocol for Reversed{
fn __reversed__(&self, py: Python) -> PyResult<&'static str> {
fn __reversed__(&self) -> PyResult<&'static str> {
println!("__reversed__");
Ok("I am reversed")
}
@ -619,7 +620,7 @@ struct Contains {}
#[py::proto]
impl PySequenceProtocol for Contains {
fn __contains__(&self, py: Python, item: i32) -> PyResult<bool> {
fn __contains__(&self, item: i32) -> PyResult<bool> {
Ok(item >= 0)
}
}
@ -643,19 +644,19 @@ struct UnaryArithmetic {}
#[py::proto]
impl PyNumberProtocol for UnaryArithmetic {
fn __neg__(&self, py: Python) -> PyResult<&'static str> {
fn __neg__(&self) -> PyResult<&'static str> {
Ok("neg")
}
fn __pos__(&self, py: Python) -> PyResult<&'static str> {
fn __pos__(&self) -> PyResult<&'static str> {
Ok("pos")
}
fn __abs__(&self, py: Python) -> PyResult<&'static str> {
fn __abs__(&self) -> PyResult<&'static str> {
Ok("abs")
}
fn __invert__(&self, py: Python) -> PyResult<&'static str> {
fn __invert__(&self) -> PyResult<&'static str> {
Ok("invert")
}
}
@ -678,42 +679,42 @@ struct BinaryArithmetic {}
#[py::proto]
impl PyObjectProtocol for BinaryArithmetic {
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
fn __repr__(&self) -> PyResult<&'static str> {
Ok("BA")
}
}
#[py::proto]
impl PyNumberProtocol for BinaryArithmetic {
fn __add__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __add__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} + {:?}", self.as_object(), rhs))
}
fn __sub__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __sub__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} - {:?}", self.as_object(), rhs))
}
fn __mul__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __mul__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} * {:?}", self.as_object(), rhs))
}
fn __lshift__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __lshift__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} << {:?}", self.as_object(), rhs))
}
fn __rshift__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __rshift__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} >> {:?}", self.as_object(), rhs))
}
fn __and__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __and__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} & {:?}", self.as_object(), rhs))
}
fn __xor__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __xor__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} ^ {:?}", self.as_object(), rhs))
}
fn __or__(&self, py: Python, rhs: PyObject) -> PyResult<String> {
fn __or__(&self, rhs: PyObject) -> PyResult<String> {
Ok(format!("{:?} | {:?}", self.as_object(), rhs))
}
}
@ -750,11 +751,11 @@ struct RichComparisons {}
#[py::proto]
impl PyObjectProtocol for RichComparisons {
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
fn __repr__(&self) -> PyResult<&'static str> {
Ok("RC")
}
fn __richcmp__(&self, py: Python, other: PyObject, op: CompareOp) -> PyResult<String> {
fn __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<String> {
match op {
CompareOp::Lt => Ok(format!("{:?} < {:?}", self.as_object(), other)),
CompareOp::Le => Ok(format!("{:?} <= {:?}", self.as_object(), other)),
@ -771,11 +772,11 @@ struct RichComparisons2 {}
#[py::proto]
impl PyObjectProtocol for RichComparisons2 {
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
fn __repr__(&self) -> PyResult<&'static str> {
Ok("RC2")
}
fn __richcmp__(&self, py: Python, other: PyObject, op: CompareOp) -> PyResult<PyObject> {
fn __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<PyObject> {
match op {
CompareOp::Eq => Ok(true.to_py_object(py).into_object()),
CompareOp::Ne => Ok(false.to_py_object(py).into_object()),
@ -843,49 +844,49 @@ struct InPlaceOperations {
#[py::proto]
impl PyObjectProtocol for InPlaceOperations {
fn __repr__(&self, py: Python) -> PyResult<String> {
fn __repr__(&self) -> PyResult<String> {
Ok(format!("IPO({:?})", self.value(py)))
}
}
#[py::proto]
impl PyNumberProtocol for InPlaceOperations {
fn __iadd__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __iadd__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) + other;
Ok(self.clone_ref(py))
}
fn __isub__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __isub__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) - other;
Ok(self.clone_ref(py))
}
fn __imul__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __imul__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) * other;
Ok(self.clone_ref(py))
}
fn __ilshift__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __ilshift__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) << other;
Ok(self.clone_ref(py))
}
fn __irshift__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __irshift__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) >> other;
Ok(self.clone_ref(py))
}
fn __iand__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __iand__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) & other;
Ok(self.clone_ref(py))
}
fn __ixor__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __ixor__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) ^ other;
Ok(self.clone_ref(py))
}
fn __ior__(&self, py: Python, other: u32) -> PyResult<Self> {
fn __ior__(&self, other: u32) -> PyResult<Self> {
*self.value_mut(py) = *self.value(py) | other;
Ok(self.clone_ref(py))
}
@ -927,17 +928,17 @@ struct ContextManager {
}
#[py::proto]
impl PyContextProtocol for ContextManager {
impl<'p> PyContextProtocol<'p> for ContextManager {
fn __enter__(&self, py: Python) -> PyResult<i32> {
fn __enter__(&self) -> PyResult<i32> {
Ok(42)
}
fn __exit__(&self, py: Python,
ty: Option<PyType>,
value: Option<PyObject>,
traceback: Option<PyObject>) -> PyResult<bool> {
*self.exit_called_mut(py) = true;
fn __exit__(&mut self,
ty: Option<&'p PyType>,
value: Option<&'p PyObject>,
traceback: Option<&'p PyObject>) -> PyResult<bool> {
self.exit_called = true;
if ty == Some(py.get_type::<exc::ValueError>()) {
Ok(true)
} else {
@ -973,16 +974,16 @@ struct ClassWithProperties {
#[py::methods]
impl ClassWithProperties {
fn get_num(&self, py: Python) -> PyResult<i32> {
fn get_num(&self) -> PyResult<i32> {
Ok(*self.num(py))
}
#[getter(DATA)]
fn get_data(&self, py: Python) -> PyResult<i32> {
fn get_data(&self) -> PyResult<i32> {
Ok(*self.num(py))
}
#[setter(DATA)]
fn set(&self, py: Python, value: i32) -> PyResult<()> {
fn set(&self, value: i32) -> PyResult<()> {
*self.num_mut(py) = value;
Ok(())
}
@ -1002,4 +1003,4 @@ fn class_with_properties() {
py_run!(py, inst, "assert inst.get_num() == 20");
py_run!(py, inst, "assert inst.get_num() == inst.DATA");
}
}

View File

@ -12,7 +12,7 @@ fn test_basics() {
let py = gil.python();
let v = PySlice::new(py, 1, 10, 2);
let indices = v.indices(py, 100).unwrap();
let indices = v.indices(100).unwrap();
assert_eq!(1, indices.start);
assert_eq!(10, indices.stop);
assert_eq!(2, indices.step);