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

View File

@ -45,19 +45,19 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item( let tmp = extract_decl(syn::parse_item(
quote! {fn test(&self) 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(); sig.decl.output = tmp.output.clone();
if pyres { if pyres {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type Success = #succ; type Success = #succ;
type Result = #ty; type Result = #ty;
} }
} }
} else { } else {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type Result = #ty; type Result = #ty;
} }
} }
@ -72,18 +72,18 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item( let tmp = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg: <#cls as #p<'a>>::#arg_name) arg: <#cls as #p<'p>>::#arg_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item( let tmp2 = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg: Option<<#cls as #p<'a>>::#arg_name>) arg: Option<<#cls as #p<'p>>::#arg_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2); modify_arg_ty(sig, 1, &tmp, &tmp2);
if pyres { if pyres {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type #arg_name = #arg_ty; type #arg_name = #arg_ty;
type Success = #succ; type Success = #succ;
type Result = #ty; type Result = #ty;
@ -91,7 +91,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
} }
} else { } else {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type #arg_name = #arg_ty; type #arg_name = #arg_ty;
type Result = #ty; type Result = #ty;
} }
@ -110,21 +110,21 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
let tmp = extract_decl(syn::parse_item( let tmp = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg1: <#cls as #p<'a>>::#arg1_name, arg1: <#cls as #p<'p>>::#arg1_name,
arg2: <#cls as #p<'a>>::#arg2_name) arg2: <#cls as #p<'p>>::#arg2_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item( let tmp2 = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg1: Option<<#cls as #p<'a>>::#arg1_name>, arg1: Option<<#cls as #p<'p>>::#arg1_name>,
arg2: Option<<#cls as #p<'a>>::#arg2_name>) arg2: Option<<#cls as #p<'p>>::#arg2_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2); modify_arg_ty(sig, 1, &tmp, &tmp2);
modify_arg_ty(sig, 2, &tmp, &tmp2); modify_arg_ty(sig, 2, &tmp, &tmp2);
if pyres { if pyres {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty; type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty; type #arg2_name = #arg2_ty;
type Success = #succ; type Success = #succ;
@ -133,7 +133,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
} }
} else { } else {
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty; type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty; type #arg2_name = #arg2_ty;
type Result = #ty; type Result = #ty;
@ -144,34 +144,34 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
MethodProto::Quaternary{name: _, arg1, arg2, arg3, proto} => { MethodProto::Quaternary{name: _, arg1, arg2, arg3, proto} => {
let p = syn::Ident::from(proto); let p = syn::Ident::from(proto);
let arg1_name = syn::Ident::from(arg1); 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_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_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); let succ = get_res_success(ty);
// rewrite ty // rewrite ty
let tmp = extract_decl(syn::parse_item( let tmp = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg1: <#cls as #p<'a>>::#arg1_name, arg1: <#cls as #p<'p>>::#arg1_name,
arg2: <#cls as #p<'a>>::#arg2_name, arg2: <#cls as #p<'p>>::#arg2_name,
arg3: <#cls as #p<'a>>::#arg3_name) arg3: <#cls as #p<'p>>::#arg3_name)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
let tmp2 = extract_decl(syn::parse_item( let tmp2 = extract_decl(syn::parse_item(
quote! {fn test( quote! {fn test(
&self, &self,
arg1: Option<<#cls as #p<'a>>::#arg1_name>, arg1: Option<<#cls as #p<'p>>::#arg1_name>,
arg2: Option<<#cls as #p<'a>>::#arg2_name>, arg2: Option<<#cls as #p<'p>>::#arg2_name>,
arg3: Option<<#cls as #p<'a>>::#arg3_name>) arg3: Option<<#cls as #p<'p>>::#arg3_name>)
-> <#cls as #p<'a>>::Result {}}.as_str()).unwrap()); -> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
modify_arg_ty(sig, 1, &tmp, &tmp2); modify_arg_ty(sig, 1, &tmp, &tmp2);
modify_arg_ty(sig, 2, &tmp, &tmp2); modify_arg_ty(sig, 2, &tmp, &tmp2);
modify_arg_ty(sig, 3, &tmp, &tmp2); modify_arg_ty(sig, 3, &tmp, &tmp2);
quote! { quote! {
impl<'a> #p<'a> for #cls { impl<'p> #p<'p> for #cls {
type #arg1_name = #arg1_ty; type #arg1_name = #arg1_ty;
type #arg2_name = #arg2_ty; type #arg2_name = #arg2_ty;
type #arg3_name = #arg3_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(); let arg = sig.decl.inputs[idx].clone();
match arg { match arg {
syn::FnArg::Captured(_, ref arg_ty) => { syn::FnArg::Captured(ref pat, ref arg_ty) => {
match arg_ty { match arg_ty {
&syn::Ty::Path(_, ref path) => { &syn::Ty::Path(_, ref path) => {
let seg = path.segments.last().unwrap().clone(); let seg = path.segments.last().unwrap().clone();
if seg.ident.as_ref() == "Option" { 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 { } 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(); 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> { fn check_arg_ty_and_optional<'a>(name: &'a syn::Ident, ty: &'a syn::Ty) -> Option<&'a syn::Ty> {
match ty { match ty {
&syn::Ty::Path(ref qs, ref path) => { &syn::Ty::Path(_, ref path) => {
if let &Some(ref qs) = qs { //if let &Some(ref qs) = qs {
panic!("explicit Self type in a 'qualified path' is not supported: {:?} - {:?}", // panic!("explicit Self type in a 'qualified path' is not supported: {:?} - {:?}",
name, qs); // name, qs);
} //}
if let Some(segment) = path.segments.last() { if let Some(segment) = path.segments.last() {
match segment.ident.as_ref() { match segment.ident.as_ref() {

View File

@ -22,6 +22,7 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
const #dummy_const: () = { const #dummy_const: () = {
extern crate pyo3 as _pyo3; extern crate pyo3 as _pyo3;
use std; use std;
use pyo3::python::IntoPythonPointer;
#tokens #tokens
}; };
@ -32,7 +33,7 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
let cls_name = quote! { #cls }.as_str().to_string(); let cls_name = quote! { #cls }.as_str().to_string();
quote! { quote! {
impl _pyo3::class::typeob::PyTypeInfo for #cls { impl _pyo3::typeob::PyTypeInfo for #cls {
type Type = #cls; type Type = #cls;
#[inline] #[inline]
@ -43,7 +44,7 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
#[inline] #[inline]
fn offset() -> isize { fn offset() -> isize {
let align = std::mem::align_of::<#cls>(); 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 // round base_size up to next multiple of align
((bs + align - 1) / align * align) as isize ((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 } 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 sig: &mut syn::MethodSig, meth_attrs: &mut Vec<syn::Attribute>) -> Tokens
{ {
check_generic(name, sig); check_generic(name, sig);
println!("====0");
let spec = FnSpec::parse(name, sig, meth_attrs); let spec = FnSpec::parse(name, sig, meth_attrs);
println!("====1");
match spec.tp { match spec.tp {
FnType::Fn => FnType::Fn =>
impl_py_method_def(name, &impl_wrap(cls, name, &spec)), 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, args: *mut _pyo3::ffi::PyObject,
kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
{ {
const LOCATION: &'static str = concat!( const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
stringify!(#cls), ".", stringify!(#name), "()"); _pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
_pyo3::callback::handle_callback( let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
{ _pyo3::argparse::get_kwargs(py, kwargs);
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);
let ret = { #body
#body })
};
_pyo3::PyDrop::release_ref(args, py);
_pyo3::PyDrop::release_ref(kwargs, py);
ret
})
} }
} }
} }
/// 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) /// Generate function wrapper (PyCFunction, PyCFunctionWithKeywords)
pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens { 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!( const LOCATION: &'static str = concat!(
stringify!(#cls), ".", stringify!(#name), "()"); stringify!(#cls), ".", stringify!(#name), "()");
_pyo3::callback::handle_callback( _pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
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>> =
let args: _pyo3::PyTuple = _pyo3::argparse::get_kwargs(py, kwargs);
_pyo3::PyObject::from_borrowed_ptr(py, args).unchecked_cast_into();
let kwargs: Option<_pyo3::PyDict> = _pyo3::argparse::get_kwargs(py, kwargs);
let ret = { #body
#body })
};
_pyo3::PyDrop::release_ref(args, py);
_pyo3::PyDrop::release_ref(kwargs, py);
ret
})
} }
} }
} }
@ -101,21 +106,16 @@ pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> To
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords) /// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
fn impl_wrap_getter(cls: &Box<syn::Ty>, name: &syn::Ident, _spec: &FnSpec) -> Tokens { fn impl_wrap_getter(cls: &Box<syn::Ty>, name: &syn::Ident, _spec: &FnSpec) -> Tokens {
quote! { quote! {
unsafe extern "C" fn wrap (slf: *mut _pyo3::ffi::PyObject, unsafe extern "C" fn wrap(slf: *mut _pyo3::ffi::PyObject,
_: *mut _pyo3::c_void) _: *mut _pyo3::c_void)
-> *mut _pyo3::ffi::PyObject -> *mut _pyo3::ffi::PyObject
{ {
const LOCATION: &'static str = concat!( const LOCATION: &'static str = concat!(
stringify!(#cls), ".getter_", stringify!(#name), "()"); stringify!(#cls), ".getter_", stringify!(#name), "()");
_pyo3::callback::handle_callback( _pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
{ slf.#name(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
})
} }
} }
} }
@ -131,24 +131,18 @@ fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tok
{ {
const LOCATION: &'static str = concat!( const LOCATION: &'static str = concat!(
stringify!(#cls), ".setter", stringify!(#name), "()"); stringify!(#cls), ".setter", stringify!(#name), "()");
_pyo3::callback::handle_callback( _pyo3::callback::handle(LOCATION, _pyo3::callback::UnitCallbackConverter, |py| {
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 slf = _pyo3::PyObject::from_borrowed_ptr(py, slf)
.unchecked_cast_into::<#cls>();
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
let ret = match <#val_ty as _pyo3::FromPyObject>::extract(py, &value) { match <#val_ty as _pyo3::FromPyObject>::extract(&value) {
Ok(val) => { Ok(val) => {
let ret = slf.#name(py, val); let ret = slf.#name(val);
ret.map(|o| ()) ret.map(|o| ())
} }
Err(e) => Err(e) Err(e) => Err(e)
}; }
_pyo3::PyDrop::release_ref(slf, py); })
_pyo3::PyDrop::release_ref(value, py);
ret
})
} }
} }
} }
@ -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 { 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(); let names: Vec<&syn::Ident> = spec.args.iter().map(|item| item.name).collect();
quote! { quote! {{
{ let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
let slf = _pyo3::PyObject::from_borrowed_ptr(py, slf).unchecked_cast_into::<#cls>(); slf.as_mut().#fname(#(#names),*)
let ret = slf.#fname(py, #(#names),*); }}
_pyo3::PyDrop::release_ref(slf, py);
ret
}
}
} }
fn impl_class_new(cls: &Box<syn::Ty>, fname: &syn::Ident, spec: &FnSpec) -> Tokens { 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(); let names: Vec<&syn::Ident> = spec.args.iter().map(|item| item.name).collect();
quote! { quote! {{
{ let cls: _pyo3::Py<_pyo3::PyType> = _pyo3::Py::from_borrowed_ptr(
let cls = _pyo3::PyType::from_type_ptr(py, cls); py, cls as *mut _pyo3::ffi::PyObject);
let ret = #cls::#fname(&cls, py, #(#names),*); #cls::#fname(&cls, #(#names),*)
_pyo3::PyDrop::release_ref(cls, py); }}
ret
}
}
} }
fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens { fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
if spec.args.is_empty() {
return body
}
let mut params = Vec::new(); let mut params = Vec::new();
for arg in spec.args.iter() { for arg in spec.args.iter() {
@ -223,9 +214,9 @@ fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
]; ];
let mut output = [#(#placeholders),*]; let mut output = [#(#placeholders),*];
match _pyo3::argparse::parse_args( match _pyo3::argparse::parse_args(py, Some(LOCATION), PARAMS, &args,
py, Some(LOCATION), PARAMS, &args, kwargs.as_ref(), #accept_args, #accept_kwargs,
kwargs.as_ref(), #accept_args, #accept_kwargs, &mut output) { &mut output) {
Ok(_) => { Ok(_) => {
let mut _iter = output.iter(); 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) { if spec.is_args(&name) {
quote! { quote! {
match <#ty as _pyo3::FromPyObject>::extract(py, args.as_object()) match <#ty as _pyo3::FromPyObject>::extract(&args)
{ {
Ok(#name) => { Ok(#name) => {
#body #body
@ -262,7 +253,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
} }
} }
else { else {
if let Some(ref opt_ty) = arg.optional { if let Some(_) = arg.optional {
// default value // default value
let mut default = Tokens::new(); let mut default = Tokens::new();
if let Some(d) = spec.default_value(name) { if let Some(d) = spec.default_value(name) {
@ -273,19 +264,21 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
} }
quote! { quote! {
match match _iter.next().unwrap().as_ref() { match
Some(obj) => { match _iter.next().unwrap().as_ref() {
if obj == &py.None() { Some(obj) => {
Ok(#default) if obj == &py.None() {
} else { Ok(#default)
match <#opt_ty as _pyo3::FromPyObject>::extract(py, obj) { } else {
Ok(obj) => Ok(Some(obj)), match _pyo3::callback::unref_r(obj).extract() {
Err(e) => Err(e) Ok(obj) => Ok(Some(obj)),
Err(e) => Err(e)
}
} }
} },
}, None => Ok(#default)
None => Ok(#default) }
} { {
Ok(#name) => #body, Ok(#name) => #body,
Err(e) => Err(e) Err(e) => Err(e)
} }
@ -297,7 +290,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
if obj == &py.None() { if obj == &py.None() {
Ok(#default) Ok(#default)
} else { } else {
match <#ty as _pyo3::FromPyObject>::extract(py, obj) { match _pyo3::callback::unref_r(obj).extract() {
Ok(obj) => Ok(obj), Ok(obj) => Ok(obj),
Err(e) => Err(e), Err(e) => Err(e),
} }
@ -312,8 +305,8 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
} }
else { else {
quote! { quote! {
match <#ty as _pyo3::FromPyObject>::extract( match _pyo3::callback::unref_r(
py, _iter.next().unwrap().as_ref().unwrap()) _iter.next().unwrap().as_ref().unwrap()).extract()
{ {
Ok(#name) => { Ok(#name) => {
#body #body

View File

@ -20,9 +20,9 @@ static DEFAULT_METHODS: Methods = Methods {
pub fn build_py_proto(ast: &mut syn::Item) -> Tokens { pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
match ast.node { match ast.node {
syn::ItemKind::Impl(_, _, _, ref path, ref ty, ref mut impl_items) => { syn::ItemKind::Impl(_, _, ref mut gen, ref mut path, ref ty, ref mut impl_items) => {
if let &Some(ref path) = path { if let &mut Some(ref mut path) = path {
if let Some(segment) = path.segments.last() { let tokens = if let Some(ref mut segment) = path.segments.last() {
match segment.ident.as_ref() { match segment.ident.as_ref() {
"PyObjectProtocol" => "PyObjectProtocol" =>
impl_proto_impl(ty, impl_items, &defs::OBJECT), 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), path.clone(), ty, impl_items, &DEFAULT_METHODS),
_ => { _ => {
warn!("#[proto] can not be used with this block"); warn!("#[proto] can not be used with this block");
Tokens::new() return Tokens::new()
} }
} }
} else { } else {
panic!("#[proto] can only be used with protocol trait implementations") 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 { } else {
panic!("#[proto] can only be used with protocol trait implementations") 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( let fn_spec = FnSpec::parse(
&iimpl.ident, sig, &mut iimpl.attrs); &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( py_methods.push(
quote! { quote! {

View File

@ -7,7 +7,7 @@ use libc;
use pyptr::Py; use pyptr::Py;
use python::{Python, IntoPythonPointer}; use python::{Python, IntoPythonPointer};
use objects::exc; use objects::exc;
use conversion::ToPyObject; use conversion::IntoPyObject;
use ffi::{self, Py_hash_t}; use ffi::{self, Py_hash_t};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
@ -22,7 +22,7 @@ pub trait CallbackConverter<S> {
pub struct PyObjectCallbackConverter; pub struct PyObjectCallbackConverter;
impl <S> CallbackConverter<S> for PyObjectCallbackConverter impl <S> CallbackConverter<S> for PyObjectCallbackConverter
where S: ToPyObject where S: IntoPyObject
{ {
type R = *mut ffi::PyObject; type R = *mut ffi::PyObject;
@ -94,7 +94,7 @@ pub struct IterNextResultConverter;
impl <T> CallbackConverter<Option<T>> impl <T> CallbackConverter<Option<T>>
for IterNextResultConverter for IterNextResultConverter
where T: ToPyObject where T: IntoPyObject
{ {
type R = *mut ffi::PyObject; 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> { pub unsafe fn unref<'p, T>(p: Py<'p, T>) -> &Py<T> {
{&p as *const _}.as_ref().unwrap() {&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 pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python<'p>) -> PyResult<T>, 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 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) { fn handle_panic(_py: Python, _panic: &any::Any) {
unsafe { unsafe {
ffi::PyErr_SetString(ffi::PyExc_SystemError, "Rust panic\0".as_ptr() as *const i8); 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 /// Object customization
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyObjectProtocol<'a>: PyTypeInfo + Sized + 'static { pub trait PyObjectProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __getattr__(&self, name: Self::Name) 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) 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) 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) 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) 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> { pub trait PyObjectGetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'a>; type Name: FromPyObject<'p>;
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyObjectSetAttrProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectSetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'a>; type Name: FromPyObject<'p>;
type Value: FromPyObject<'a>; type Value: FromPyObject<'p>;
type Result: Into<PyResult<()>>; type Result: Into<PyResult<()>>;
} }
pub trait PyObjectDelAttrProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectDelAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'a>; type Name: FromPyObject<'p>;
type Result: Into<PyResult<()>>; type Result: Into<PyResult<()>>;
} }
pub trait PyObjectStrProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyObjectReprProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyObjectFormatProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectFormatProtocol<'p>: PyObjectProtocol<'p> {
type Format: FromPyObject<'a>; type Format: FromPyObject<'p>;
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyObjectHashProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
type Result: Into<PyResult<usize>>; type Result: Into<PyResult<usize>>;
} }
pub trait PyObjectBoolProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
type Result: Into<PyResult<bool>>; type Result: Into<PyResult<bool>>;
} }
pub trait PyObjectBytesProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectBytesProtocol<'p>: PyObjectProtocol<'p> {
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyObjectRichcmpProtocol<'a>: PyObjectProtocol<'a> { pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
type Other: FromPyObject<'a>; type Other: FromPyObject<'p>;
type Success: ToPyObject; type Success: ToPyObject;
type Result: Into<PyResult<Self::Success>>; 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] #[inline]
fn methods() -> Vec<PyMethodDef> { fn methods() -> Vec<PyMethodDef> {
let mut methods = Vec::new(); let mut methods = Vec::new();
@ -151,14 +151,14 @@ impl<'a, T> PyObjectProtocolImpl for T where T: PyObjectProtocol<'a> {
trait PyObjectGetAttrProtocolImpl { trait PyObjectGetAttrProtocolImpl {
fn tp_getattro() -> Option<ffi::binaryfunc>; 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] #[inline]
default fn tp_getattro() -> Option<ffi::binaryfunc> { default fn tp_getattro() -> Option<ffi::binaryfunc> {
None None
} }
} }
impl<'a, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'a> impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_getattro() -> Option<ffi::binaryfunc> { fn tp_getattro() -> Option<ffi::binaryfunc> {
@ -171,21 +171,21 @@ trait PyObjectSetAttrProtocolImpl {
fn tp_setattro() -> Option<ffi::setattrofunc>; 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] #[inline]
default fn tp_setattro() -> Option<ffi::setattrofunc> { default fn tp_setattro() -> Option<ffi::setattrofunc> {
None None
} }
} }
impl<'a, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'a> impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_setattro() -> Option<ffi::setattrofunc> { 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'a> where T: PyObjectSetAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__setattr__()"; const LOCATION: &'static str = "T.__setattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -218,21 +218,21 @@ impl<'a, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'
trait PyObjectDelAttrProtocolImpl { trait PyObjectDelAttrProtocolImpl {
fn tp_delattro() -> Option<ffi::setattrofunc>; 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] #[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> { default fn tp_delattro() -> Option<ffi::setattrofunc> {
None None
} }
} }
impl<'a, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'a> impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'p>
{ {
#[inline] #[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> { 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectDelAttrProtocol<'a> where T: PyObjectDelAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__detattr__()"; const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -257,15 +257,15 @@ impl<'a, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'
} }
impl<'a, T> PyObjectDelAttrProtocolImpl for T impl<'p, T> PyObjectDelAttrProtocolImpl for T
where T: PyObjectSetAttrProtocol<'a> + PyObjectDelAttrProtocol<'a> where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_delattro() -> Option<ffi::setattrofunc> { 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'a> + PyObjectDelAttrProtocol<'a> where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__detattr__()"; const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -301,14 +301,14 @@ impl<'a, T> PyObjectDelAttrProtocolImpl for T
trait PyObjectStrProtocolImpl { trait PyObjectStrProtocolImpl {
fn tp_str() -> Option<ffi::unaryfunc>; 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] #[inline]
default fn tp_str() -> Option<ffi::unaryfunc> { default fn tp_str() -> Option<ffi::unaryfunc> {
None None
} }
} }
impl<'a, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'a> impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_str() -> Option<ffi::unaryfunc> { fn tp_str() -> Option<ffi::unaryfunc> {
@ -319,14 +319,14 @@ impl<'a, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'a>
trait PyObjectReprProtocolImpl { trait PyObjectReprProtocolImpl {
fn tp_repr() -> Option<ffi::unaryfunc>; 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] #[inline]
default fn tp_repr() -> Option<ffi::unaryfunc> { default fn tp_repr() -> Option<ffi::unaryfunc> {
None None
} }
} }
impl<'a, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'a> impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'p>
{ {
#[inline] #[inline]
fn tp_repr() -> Option<ffi::unaryfunc> { fn tp_repr() -> Option<ffi::unaryfunc> {
@ -338,7 +338,7 @@ impl<'a, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'a>
pub trait PyObjectFormatProtocolImpl { pub trait PyObjectFormatProtocolImpl {
fn __format__() -> Option<PyMethodDef>; 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] #[inline]
default fn __format__() -> Option<PyMethodDef> { default fn __format__() -> Option<PyMethodDef> {
@ -350,7 +350,7 @@ impl<'a, T> PyObjectFormatProtocolImpl for T where T: PyObjectProtocol<'a>
pub trait PyObjectBytesProtocolImpl { pub trait PyObjectBytesProtocolImpl {
fn __bytes__() -> Option<PyMethodDef>; 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] #[inline]
default fn __bytes__() -> Option<PyMethodDef> { default fn __bytes__() -> Option<PyMethodDef> {
@ -362,14 +362,14 @@ impl<'a, T> PyObjectBytesProtocolImpl for T where T: PyObjectProtocol<'a>
trait PyObjectHashProtocolImpl { trait PyObjectHashProtocolImpl {
fn tp_hash() -> Option<ffi::hashfunc>; 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] #[inline]
default fn tp_hash() -> Option<ffi::hashfunc> { default fn tp_hash() -> Option<ffi::hashfunc> {
None None
} }
} }
impl<'a, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'a> impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'p>
{ {
#[inline] #[inline]
fn tp_hash() -> Option<ffi::hashfunc> { fn tp_hash() -> Option<ffi::hashfunc> {
@ -380,14 +380,14 @@ impl<'a, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'a>
trait PyObjectBoolProtocolImpl { trait PyObjectBoolProtocolImpl {
fn nb_bool() -> Option<ffi::inquiry>; 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] #[inline]
default fn nb_bool() -> Option<ffi::inquiry> { default fn nb_bool() -> Option<ffi::inquiry> {
None None
} }
} }
impl<'a, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'a> impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'p>
{ {
#[inline] #[inline]
fn nb_bool() -> Option<ffi::inquiry> { fn nb_bool() -> Option<ffi::inquiry> {
@ -398,21 +398,21 @@ impl<'a, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'a>
trait PyObjectRichcmpProtocolImpl { trait PyObjectRichcmpProtocolImpl {
fn tp_richcompare() -> Option<ffi::richcmpfunc>; 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] #[inline]
default fn tp_richcompare() -> Option<ffi::richcmpfunc> { default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
None None
} }
} }
impl<'a, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'a> impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'p>
{ {
#[inline] #[inline]
fn tp_richcompare() -> Option<ffi::richcmpfunc> { fn tp_richcompare() -> Option<ffi::richcmpfunc> {
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, arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject op: c_int) -> *mut ffi::PyObject
where T: PyObjectRichcmpProtocol<'a> where T: PyObjectRichcmpProtocol<'p>
{ {
const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()"); const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()");
::callback::handle(LOCATION, PyObjectCallbackConverter, |py| { ::callback::handle(LOCATION, PyObjectCallbackConverter, |py| {

View File

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

View File

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

View File

@ -8,27 +8,25 @@
use ffi; use ffi;
use err::PyResult; use err::PyResult;
use python::{Python, PythonObject}; use typeob::PyTypeInfo;
use callback::PyObjectCallbackConverter; use callback::PyObjectCallbackConverter;
/// Iterator protocol /// Iterator protocol
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyIterProtocol : PythonObject { pub trait PyIterProtocol<'p> : PyTypeInfo {
fn __iter__(&self, py: Python) fn __iter__(&self) -> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
-> Self::Result where Self: PyIterIterProtocol { unimplemented!() }
fn __next__(&self, py: Python) fn __next__(&self) -> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
-> Self::Result where Self: PyIterNextProtocol { unimplemented!() }
} }
pub trait PyIterIterProtocol: PyIterProtocol { pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
type Success: ::ToPyObject; type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
pub trait PyIterNextProtocol: PyIterProtocol { pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
type Success: ::ToPyObject; type Success: ::ToPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Self::Success>>;
} }
@ -44,7 +42,7 @@ impl<T> PyIterProtocolImpl for T {
default fn tp_as_iter(_: &mut ffi::PyTypeObject) {} 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] #[inline]
fn tp_as_iter(typeob: &mut ffi::PyTypeObject) { fn tp_as_iter(typeob: &mut ffi::PyTypeObject) {
typeob.tp_iter = Self::tp_iter(); typeob.tp_iter = Self::tp_iter();
@ -56,8 +54,7 @@ trait PyIterIterProtocolImpl {
fn tp_iter() -> Option<ffi::getiterfunc>; fn tp_iter() -> Option<ffi::getiterfunc>;
} }
impl<T> PyIterIterProtocolImpl for T impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p>
where T: PyIterProtocol
{ {
#[inline] #[inline]
default fn tp_iter() -> Option<ffi::getiterfunc> { default fn tp_iter() -> Option<ffi::getiterfunc> {
@ -65,12 +62,11 @@ impl<T> PyIterIterProtocolImpl for T
} }
} }
impl<T> PyIterIterProtocolImpl for T impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterIterProtocol<'p>
where T: PyIterIterProtocol
{ {
#[inline] #[inline]
fn tp_iter() -> Option<ffi::getiterfunc> { 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>; fn tp_iternext() -> Option<ffi::iternextfunc>;
} }
impl<T> PyIterNextProtocolImpl for T impl<'p, T> PyIterNextProtocolImpl for T
where T: PyIterProtocol where T: PyIterProtocol<'p>
{ {
#[inline] #[inline]
default fn tp_iternext() -> Option<ffi::iternextfunc> { default fn tp_iternext() -> Option<ffi::iternextfunc> {
@ -87,11 +83,11 @@ impl<T> PyIterNextProtocolImpl for T
} }
} }
impl<T> PyIterNextProtocolImpl for T impl<'p, T> PyIterNextProtocolImpl for T
where T: PyIterNextProtocol where T: PyIterNextProtocol<'p>
{ {
#[inline] #[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> { 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 async;
pub mod basic; pub mod basic;
//pub mod buffer; pub mod buffer;
//pub mod context; pub mod context;
pub mod descr; pub mod descr;
pub mod mapping; pub mod mapping;
pub mod methods; pub mod methods;
pub mod number; pub mod number;
//pub mod iter; pub mod iter;
pub mod gc; pub mod gc;
pub mod sequence; pub mod sequence;
pub use self::basic::PyObjectProtocol; pub use self::basic::PyObjectProtocol;
pub use self::async::PyAsyncProtocol; pub use self::async::PyAsyncProtocol;
//pub use self::iter::PyIterProtocol; pub use self::iter::PyIterProtocol;
//pub use self::buffer::PyBufferProtocol; pub use self::buffer::PyBufferProtocol;
//pub use self::context::PyContextProtocol; pub use self::context::PyContextProtocol;
pub use self::descr::PyDescrProtocol; pub use self::descr::PyDescrProtocol;
pub use self::number::PyNumberProtocol; pub use self::number::PyNumberProtocol;
pub use self::mapping::PyMappingProtocol; pub use self::mapping::PyMappingProtocol;

View File

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

View File

@ -12,14 +12,6 @@ pub trait ToPyObject {
/// Converts self into a Python object. /// Converts self into a Python object.
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject>; 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 /// Converts self into a Python object and calls the specified closure
/// on the native FFI pointer underlying the Python object. /// on the native FFI pointer underlying the Python object.
/// ///
@ -32,26 +24,18 @@ pub trait ToPyObject {
let obj = self.to_object(py).into_object(); let obj = self.to_object(py).into_object();
f(obj.as_ptr()) 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. /// Conversion trait that allows various objects to be converted into PyTuple object.
pub trait ToPyTuple { 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 /// Identity conversion: allows using existing `PyObject` instances where
/// `T: ToPyObject` is expected. /// `T: ToPyObject` is expected.
// ToPyObject for references // 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) <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] #[inline]
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R where F: FnOnce(*mut ffi::PyObject) -> R
@ -148,6 +137,9 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
None => py.None() None => py.None()
} }
} }
}
impl <T> IntoPyObject for Option<T> where T: IntoPyObject {
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> { fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
match self { match self {
@ -157,6 +149,7 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
} }
} }
/// `()` is converted to Python `None`. /// `()` is converted to Python `None`.
impl ToPyObject for () { impl ToPyObject for () {
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> { 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> fn extract<S>(obj: &'source Py<'source, S>) -> PyResult<Self>
where S: PyTypeInfo where S: PyTypeInfo
{ {

View File

@ -69,9 +69,9 @@ pub use pyptr::{Py, PyPtr};
pub use err::{PyErr, PyResult, PyDowncastError}; pub use err::{PyErr, PyResult, PyDowncastError};
pub use objects::*; pub use objects::*;
pub use python::Python; pub use python::{AsPy, Python};
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_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 use class::{CompareOp};
pub mod class; pub mod class;
pub use class::*; pub use class::*;
@ -104,14 +104,14 @@ macro_rules! py_replace_expr {
($_t:tt $sub:expr) => {$sub}; ($_t:tt $sub:expr) => {$sub};
} }
mod python; pub mod python;
mod err; mod err;
mod callback;
mod conversion; mod conversion;
mod objects; mod objects;
mod objectprotocol; mod objectprotocol;
mod pythonrun; mod pythonrun;
mod typeob; pub mod callback;
pub mod typeob;
pub mod argparse; pub mod argparse;
pub mod function; pub mod function;
pub mod buffer; pub mod buffer;

View File

@ -6,8 +6,8 @@ use std::ops::Deref;
use std::convert::{AsRef, AsMut}; use std::convert::{AsRef, AsMut};
use ffi; use ffi;
use ::ToPyObject;
use err::{PyErr, PyResult, PyDowncastError}; use err::{PyErr, PyResult, PyDowncastError};
use conversion::{ToPyObject, IntoPyObject};
use python::{Python, ToPythonPointer, IntoPythonPointer}; use python::{Python, ToPythonPointer, IntoPythonPointer};
use objects::PyObject; use objects::PyObject;
use typeob::{PyTypeInfo, PyObjectAlloc}; 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] #[inline]
default fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> { default fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
PyObject::from_owned_ptr(py, self.inner) 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] #[inline]
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R where F: FnOnce(*mut ffi::PyObject) -> R
@ -451,3 +447,21 @@ impl<'a, T> ToPyObject for Py<'a, T> {
f(self.inner) 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 /// Create new PyObject instance
#[inline] #[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> where T: PyTypeInfo + PyObjectAlloc<Type=T>
{ {
::Py::new(self, value) Py::new(self, value).unwrap()
} }
/// Gets the Python builtin value `None`. /// 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); <T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object);
// number methods // 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; static mut NB_METHODS: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
*(unsafe { &mut NB_METHODS }) = meth; *(unsafe { &mut NB_METHODS }) = meth;
type_object.tp_as_number = unsafe { &mut NB_METHODS }; type_object.tp_as_number = unsafe { &mut NB_METHODS };
mem::forget(meth); mem::forget(meth);
} else { } else {
type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods; type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods;
}*/ }
// mapping methods // mapping methods
if let Some(meth) = <T as class::mapping::PyMappingProtocolImpl>::tp_as_mapping() { 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 // 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; static mut BUFFER_PROCS: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
*(unsafe { &mut BUFFER_PROCS }) = meth; *(unsafe { &mut BUFFER_PROCS }) = meth;
type_object.tp_as_buffer = unsafe { &mut BUFFER_PROCS }; 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 // strange
mem::forget(props); mem::forget(props);
}*/ }
// register type object // register type object
unsafe { unsafe {
@ -301,7 +301,6 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
r r
} }
/*
fn py_class_method_defs<T>() -> (Option<ffi::newfunc>, fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
Option<ffi::PyCFunctionWithKeywords>, Option<ffi::PyCFunctionWithKeywords>,
Vec<ffi::PyMethodDef>) { Vec<ffi::PyMethodDef>) {
@ -378,4 +377,4 @@ fn py_class_properties<T>() -> Vec<ffi::PyGetSetDef> {
} }
defs.values().map(|i| i.clone()).collect() defs.values().map(|i| i.clone()).collect()
}*/ }

View File

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

View File

@ -12,7 +12,7 @@ fn test_basics() {
let py = gil.python(); let py = gil.python();
let v = PySlice::new(py, 1, 10, 2); 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!(1, indices.start);
assert_eq!(10, indices.stop); assert_eq!(10, indices.stop);
assert_eq!(2, indices.step); assert_eq!(2, indices.step);