introduce PythonToken; cleanup number protocol
This commit is contained in:
parent
467cce6c6d
commit
6205be98b8
|
@ -439,68 +439,68 @@ pub const NUM: Proto = Proto {
|
||||||
MethodProto::Binary {
|
MethodProto::Binary {
|
||||||
name: "__iadd__",
|
name: "__iadd__",
|
||||||
arg: "Other",
|
arg: "Other",
|
||||||
pyres: true,
|
pyres: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
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: false,
|
||||||
proto: "::pyo3::class::number::PyNumberIOrProtocol"},
|
proto: "::pyo3::class::number::PyNumberIOrProtocol"},
|
||||||
|
|
||||||
MethodProto::Unary {
|
MethodProto::Unary {
|
||||||
|
|
|
@ -42,12 +42,14 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
match *meth {
|
match *meth {
|
||||||
MethodProto::Unary{name: _, pyres, proto} => {
|
MethodProto::Unary{name: _, pyres, proto} => {
|
||||||
let p = syn::Ident::from(proto);
|
let p = syn::Ident::from(proto);
|
||||||
let succ = get_res_success(ty);
|
let (ty, succ) = get_res_success(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<'p>>::Result {}}.as_str()).unwrap());
|
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
|
||||||
sig.decl.output = tmp.output.clone();
|
sig.decl.output = tmp.output.clone();
|
||||||
|
modify_self_ty(sig);
|
||||||
|
modify_py_ty(sig);
|
||||||
|
|
||||||
if pyres {
|
if pyres {
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -65,14 +67,14 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MethodProto::Binary{name: n, arg, pyres, proto} => {
|
MethodProto::Binary{name: n, arg, pyres, proto} => {
|
||||||
if sig.decl.inputs.len() < 2 {
|
if sig.decl.inputs.len() <= 2 {
|
||||||
println!("Not enough arguments for {}", n);
|
println!("Not enough arguments for {}", n);
|
||||||
return Tokens::new();
|
return Tokens::new();
|
||||||
}
|
}
|
||||||
let p = syn::Ident::from(proto);
|
let p = syn::Ident::from(proto);
|
||||||
let arg_name = syn::Ident::from(arg);
|
let arg_name = syn::Ident::from(arg);
|
||||||
let arg_ty = get_arg_ty(sig, 2);
|
let arg_ty = get_arg_ty(sig, 2);
|
||||||
let succ = get_res_success(ty);
|
let (ty, succ) = get_res_success(ty);
|
||||||
|
|
||||||
let tmp = extract_decl(syn::parse_item(
|
let tmp = extract_decl(syn::parse_item(
|
||||||
quote! {fn test(
|
quote! {fn test(
|
||||||
|
@ -85,6 +87,8 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
arg: Option<<#cls as #p<'p>>::#arg_name>)
|
arg: Option<<#cls as #p<'p>>::#arg_name>)
|
||||||
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
|
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
|
||||||
modify_arg_ty(sig, 2, &tmp, &tmp2);
|
modify_arg_ty(sig, 2, &tmp, &tmp2);
|
||||||
|
modify_self_ty(sig);
|
||||||
|
modify_py_ty(sig);
|
||||||
|
|
||||||
if pyres {
|
if pyres {
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -104,7 +108,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MethodProto::Ternary{name: n, arg1, arg2, pyres, proto} => {
|
MethodProto::Ternary{name: n, arg1, arg2, pyres, proto} => {
|
||||||
if sig.decl.inputs.len() < 3 {
|
if sig.decl.inputs.len() <= 3 {
|
||||||
print_err(format!("Not enough arguments {}", n), quote!(sig));
|
print_err(format!("Not enough arguments {}", n), quote!(sig));
|
||||||
return Tokens::new();
|
return Tokens::new();
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
let arg1_ty = get_arg_ty(sig, 2);
|
let arg1_ty = get_arg_ty(sig, 2);
|
||||||
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, 3);
|
||||||
let succ = get_res_success(ty);
|
let (ty, succ) = get_res_success(ty);
|
||||||
|
|
||||||
// rewrite ty
|
// rewrite ty
|
||||||
let tmp = extract_decl(syn::parse_item(
|
let tmp = extract_decl(syn::parse_item(
|
||||||
|
@ -130,6 +134,8 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
|
-> <#cls as #p<'p>>::Result {}}.as_str()).unwrap());
|
||||||
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);
|
||||||
|
modify_self_ty(sig);
|
||||||
|
modify_py_ty(sig);
|
||||||
|
|
||||||
if pyres {
|
if pyres {
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -151,7 +157,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MethodProto::Quaternary{name: n, arg1, arg2, arg3, proto} => {
|
MethodProto::Quaternary{name: n, arg1, arg2, arg3, proto} => {
|
||||||
if sig.decl.inputs.len() < 4 {
|
if sig.decl.inputs.len() <= 4 {
|
||||||
print_err(format!("Not enough arguments {}", n), quote!(sig));
|
print_err(format!("Not enough arguments {}", n), quote!(sig));
|
||||||
return Tokens::new();
|
return Tokens::new();
|
||||||
}
|
}
|
||||||
|
@ -162,7 +168,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
let arg2_ty = get_arg_ty(sig, 3);
|
let arg2_ty = get_arg_ty(sig, 3);
|
||||||
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, 4);
|
||||||
let succ = get_res_success(ty);
|
let (ty, succ) = get_res_success(ty);
|
||||||
|
|
||||||
// rewrite ty
|
// rewrite ty
|
||||||
let tmp = extract_decl(syn::parse_item(
|
let tmp = extract_decl(syn::parse_item(
|
||||||
|
@ -182,6 +188,8 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
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);
|
||||||
modify_arg_ty(sig, 4, &tmp, &tmp2);
|
modify_arg_ty(sig, 4, &tmp, &tmp2);
|
||||||
|
modify_self_ty(sig);
|
||||||
|
modify_py_ty(sig);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl<'p> #p<'p> for #cls {
|
impl<'p> #p<'p> for #cls {
|
||||||
|
@ -202,7 +210,7 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
|
|
||||||
// TODO: better arg ty detection
|
// TODO: better arg ty detection
|
||||||
fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
|
fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
|
||||||
match sig.decl.inputs[idx] {
|
let mut ty = match sig.decl.inputs[idx] {
|
||||||
syn::FnArg::Captured(_, ref arg_ty) => {
|
syn::FnArg::Captured(_, ref arg_ty) => {
|
||||||
match arg_ty {
|
match arg_ty {
|
||||||
&syn::Ty::Path(_, ref path) => {
|
&syn::Ty::Path(_, ref path) => {
|
||||||
|
@ -220,25 +228,38 @@ fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
|
||||||
}
|
}
|
||||||
arg_ty.clone()
|
arg_ty.clone()
|
||||||
},
|
},
|
||||||
_ => {
|
_ => arg_ty.clone()
|
||||||
arg_ty.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ =>
|
_ => panic!("fn arg type is not supported"),
|
||||||
panic!("fn arg type is not supported"),
|
};
|
||||||
|
|
||||||
|
match ty {
|
||||||
|
syn::Ty::Rptr(ref mut lifetime, _) => {
|
||||||
|
match lifetime {
|
||||||
|
&mut None => {
|
||||||
|
*lifetime = Some(syn::Lifetime {ident: syn::Ident::from("'p")})
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
fn get_res_success(ty: &syn::Ty) -> syn::Ty {
|
fn get_res_success(ty: &syn::Ty) -> (Tokens, syn::Ty) {
|
||||||
match ty {
|
let result;
|
||||||
|
let mut succ = match ty {
|
||||||
&syn::Ty::Path(_, ref path) => {
|
&syn::Ty::Path(_, ref path) => {
|
||||||
if let Some(segment) = path.segments.last() {
|
if let Some(segment) = path.segments.last() {
|
||||||
match segment.ident.as_ref() {
|
match segment.ident.as_ref() {
|
||||||
// check result type
|
// check result type
|
||||||
"PyResult" => match segment.parameters {
|
"PyResult" => match segment.parameters {
|
||||||
syn::PathParameters::AngleBracketed(ref data) => {
|
syn::PathParameters::AngleBracketed(ref data) => {
|
||||||
|
result = true;
|
||||||
data.types[0].clone()
|
data.types[0].clone()
|
||||||
},
|
},
|
||||||
_ => panic!("fn result type is not supported"),
|
_ => panic!("fn result type is not supported"),
|
||||||
|
@ -253,7 +274,40 @@ fn get_res_success(ty: &syn::Ty) -> syn::Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!("not supported: {:?}", ty),
|
_ => panic!("not supported: {:?}", ty),
|
||||||
|
};
|
||||||
|
|
||||||
|
// add lifetime to Py<T>
|
||||||
|
match succ {
|
||||||
|
syn::Ty::Path(_, ref mut path) => {
|
||||||
|
let last = path.segments.len()-1;
|
||||||
|
let seg = path.segments[last].clone();
|
||||||
|
|
||||||
|
if seg.ident.as_ref() == "Py" {
|
||||||
|
if let syn::PathParameters::AngleBracketed(ref data) = seg.parameters {
|
||||||
|
path.segments[last] = syn::PathSegment{
|
||||||
|
ident: seg.ident.clone(),
|
||||||
|
parameters: syn::PathParameters::AngleBracketed(
|
||||||
|
syn::AngleBracketedParameterData{
|
||||||
|
lifetimes: vec![syn::Lifetime {
|
||||||
|
ident: syn::Ident::from("'p")}],
|
||||||
|
types: data.types.clone(),
|
||||||
|
bindings: data.bindings.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// result
|
||||||
|
let res = if result {
|
||||||
|
quote! {PyResult<#succ>}
|
||||||
|
} else {
|
||||||
|
quote! {#ty}
|
||||||
|
};
|
||||||
|
|
||||||
|
(res, succ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,13 +339,54 @@ fn modify_arg_ty(sig: &mut syn::MethodSig, idx: usize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ =>
|
_ => panic!("not supported"),
|
||||||
panic!("not supported"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sig.decl.output = decl1.output.clone();
|
sig.decl.output = decl1.output.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn modify_self_ty(sig: &mut syn::MethodSig)
|
||||||
|
{
|
||||||
|
match sig.decl.inputs[0] {
|
||||||
|
syn::FnArg::SelfRef(ref mut lifetime, _) => {
|
||||||
|
*lifetime = Some(syn::Lifetime {ident: syn::Ident::from("'p")})
|
||||||
|
},
|
||||||
|
_ => panic!("not supported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify Python signature
|
||||||
|
fn modify_py_ty(sig: &mut syn::MethodSig)
|
||||||
|
{
|
||||||
|
match sig.decl.inputs[1] {
|
||||||
|
syn::FnArg::Captured(_, ref mut arg_ty) => {
|
||||||
|
match arg_ty {
|
||||||
|
&mut syn::Ty::Path(_, ref mut path) => {
|
||||||
|
let last = path.segments.len()-1;
|
||||||
|
let seg = path.segments[last].clone();
|
||||||
|
if seg.ident.as_ref() == "Python" {
|
||||||
|
if let syn::PathParameters::AngleBracketed(ref data) = seg.parameters {
|
||||||
|
path.segments[last] = syn::PathSegment{
|
||||||
|
ident: seg.ident.clone(),
|
||||||
|
parameters: syn::PathParameters::AngleBracketed(
|
||||||
|
syn::AngleBracketedParameterData{
|
||||||
|
lifetimes: vec![syn::Lifetime {
|
||||||
|
ident: syn::Ident::from("'p")}],
|
||||||
|
types: data.types.clone(),
|
||||||
|
bindings: data.bindings.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("not supported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn fix_name(pat: &syn::Pat, arg: &syn::FnArg) -> syn::FnArg {
|
fn fix_name(pat: &syn::Pat, arg: &syn::FnArg) -> syn::FnArg {
|
||||||
match arg {
|
match arg {
|
||||||
&syn::FnArg::Captured(_, ref arg_ty) =>
|
&syn::FnArg::Captured(_, ref arg_ty) =>
|
||||||
|
|
|
@ -8,7 +8,8 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
||||||
let base = syn::Ident::from("_pyo3::PyObject");
|
let base = syn::Ident::from("_pyo3::PyObject");
|
||||||
|
|
||||||
match ast.body {
|
match ast.body {
|
||||||
syn::Body::Struct(syn::VariantData::Struct(_)) => (),
|
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
||||||
|
},
|
||||||
_ => panic!("#[class] can only be used with notmal structs"),
|
_ => panic!("#[class] can only be used with notmal structs"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +23,6 @@ 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
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
||||||
|
let token_name = syn::Ident::from("__py_token");
|
||||||
let cls_name = quote! { #cls }.as_str().to_string();
|
let cls_name = quote! { #cls }.as_str().to_string();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -60,12 +61,22 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl _pyo3::IntoPyObject for #cls {
|
impl _pyo3::python::ToPythonPointer for #cls {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
|
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||||
{
|
let offset = <#cls as _pyo3::typeob::PyTypeInfo>::offset();
|
||||||
let ptr = py.init(self).into_ptr();
|
unsafe {
|
||||||
_pyo3::PyObject::from_owned_ptr(py, ptr)
|
{self as *const _ as *mut u8}.offset(-offset) as *mut _pyo3::ffi::PyObject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl _pyo3::python::PyClone for #cls {
|
||||||
|
fn clone_ref(&self) -> PyPtr<#cls> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||||
|
_pyo3::PyPtr::from_borrowed_ptr(ptr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub fn impl_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens
|
||||||
kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
|
kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
|
||||||
{
|
{
|
||||||
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
||||||
_pyo3::callback::cb_meth::<_, *mut _pyo3::ffi::PyObject>(LOCATION, |py| {
|
_pyo3::callback::cb_meth(LOCATION, |py| {
|
||||||
let mut slf: Py<#cls> = Py::from_borrowed_ptr(py, slf);
|
let mut slf: Py<#cls> = Py::from_borrowed_ptr(py, slf);
|
||||||
|
|
||||||
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
||||||
|
@ -70,18 +70,24 @@ pub fn impl_proto_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) ->
|
||||||
let body = impl_arg_params(&spec, cb);
|
let body = impl_arg_params(&spec, cb);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
unsafe extern "C" fn wrap<'p>(
|
#[allow(unused_mut)]
|
||||||
slf: *mut _pyo3::ffi::PyObject,
|
unsafe extern "C" fn wrap(slf: *mut _pyo3::ffi::PyObject,
|
||||||
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!(stringify!(#cls),".",stringify!(#name),"()");
|
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
||||||
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
|
_pyo3::callback::cb_meth(LOCATION, |py| {
|
||||||
|
let mut slf: Py<#cls> = Py::from_borrowed_ptr(py, slf);
|
||||||
|
|
||||||
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
||||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||||
|
|
||||||
#body
|
let result = {
|
||||||
|
#body
|
||||||
|
};
|
||||||
|
_pyo3::callback::cb_convert(
|
||||||
|
_pyo3::callback::PyObjectCallbackConverter, py, result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,20 +97,28 @@ pub fn impl_proto_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) ->
|
||||||
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 {
|
||||||
let cb = impl_class_new(cls, name, spec);
|
let cb = impl_class_new(cls, name, spec);
|
||||||
let body = impl_arg_params(spec, cb);
|
let body = impl_arg_params(spec, cb);
|
||||||
|
let output = &spec.output;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
#[allow(unused_mut)]
|
||||||
unsafe extern "C" fn wrap(cls: *mut _pyo3::ffi::PyTypeObject,
|
unsafe extern "C" fn wrap(cls: *mut _pyo3::ffi::PyTypeObject,
|
||||||
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::cb_meth(LOCATION, |py| {
|
||||||
|
let cls: _pyo3::Py<_pyo3::PyType> = _pyo3::Py::from_borrowed_ptr(
|
||||||
|
py, cls as *mut _pyo3::ffi::PyObject);
|
||||||
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
||||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||||
|
|
||||||
#body
|
let result: #output = {
|
||||||
|
#body
|
||||||
|
};
|
||||||
|
_pyo3::callback::cb_convert(
|
||||||
|
_pyo3::callback::PyObjectCallbackConverter, py, result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,8 +134,8 @@ fn impl_wrap_getter(cls: &Box<syn::Ty>, name: &syn::Ident, _spec: &FnSpec) -> To
|
||||||
{
|
{
|
||||||
const LOCATION: &'static str = concat!(
|
const LOCATION: &'static str = concat!(
|
||||||
stringify!(#cls), ".getter_", stringify!(#name), "()");
|
stringify!(#cls), ".getter_", stringify!(#name), "()");
|
||||||
_pyo3::callback::handle(LOCATION, _pyo3::callback::PyObjectCallbackConverter, |py| {
|
_pyo3::callback::cb_unary::<#cls, _, _, _>(
|
||||||
let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
|
LOCATION, slf, _pyo3::callback::PyObjectCallbackConverter, |py, slf| {
|
||||||
slf.#name(py)
|
slf.#name(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -130,25 +144,33 @@ fn impl_wrap_getter(cls: &Box<syn::Ty>, name: &syn::Ident, _spec: &FnSpec) -> To
|
||||||
|
|
||||||
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
|
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
|
||||||
fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens {
|
fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens {
|
||||||
|
if spec.args.len() < 1 {
|
||||||
|
println!("Not enough arguments for setter {}::{}", quote!{#cls}, name);
|
||||||
|
}
|
||||||
let val_ty = spec.args[0].ty;
|
let val_ty = spec.args[0].ty;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
#[allow(unused_mut)]
|
||||||
unsafe extern "C" fn wrap(slf: *mut _pyo3::ffi::PyObject,
|
unsafe extern "C" fn wrap(slf: *mut _pyo3::ffi::PyObject,
|
||||||
value: *mut _pyo3::ffi::PyObject,
|
value: *mut _pyo3::ffi::PyObject,
|
||||||
_: *mut _pyo3::c_void) -> _pyo3::c_int
|
_: *mut _pyo3::c_void) -> _pyo3::c_int
|
||||||
{
|
{
|
||||||
const LOCATION: &'static str = concat!(
|
const LOCATION: &'static str = concat!(
|
||||||
stringify!(#cls), ".setter", stringify!(#name), "()");
|
stringify!(#cls), ".setter", stringify!(#name), "()");
|
||||||
_pyo3::callback::handle(LOCATION, _pyo3::callback::UnitCallbackConverter, |py| {
|
_pyo3::callback::cb_setter(LOCATION, |py| {
|
||||||
let slf: _pyo3::Py<#cls> = _pyo3::Py::from_borrowed_ptr(py, slf);
|
let mut slf = _pyo3::Py::<#cls>::from_borrowed_ptr(py, slf);
|
||||||
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
|
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
|
||||||
|
|
||||||
match <#val_ty as _pyo3::FromPyObject>::extract(&value) {
|
let result = match <#val_ty as _pyo3::FromPyObject>::extract(&value) {
|
||||||
Ok(val) => {
|
Ok(val) => slf.#name(py, val),
|
||||||
let ret = slf.#name(val);
|
|
||||||
ret.map(|o| ())
|
|
||||||
}
|
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(_) => 0,
|
||||||
|
Err(e) => {
|
||||||
|
e.restore(py);
|
||||||
|
-1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -156,19 +178,17 @@ 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! {{
|
||||||
slf.#fname(py, #(#names),*)
|
slf.as_mut().#fname(py, #(#names),*)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
#cls::#fname(&cls, py, #(#names),*)
|
||||||
py, cls as *mut _pyo3::ffi::PyObject);
|
|
||||||
#cls::#fname(&cls, #(#names),*)
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,8 +95,7 @@ fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &de
|
||||||
let name = syn::Ident::from(m.name);
|
let name = syn::Ident::from(m.name);
|
||||||
let proto = syn::Ident::from(m.proto);
|
let proto = syn::Ident::from(m.proto);
|
||||||
|
|
||||||
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_proto_wrap(ty, &iimpl.ident, &fn_spec);
|
let meth = py_method::impl_proto_wrap(ty, &iimpl.ident, &fn_spec);
|
||||||
|
|
||||||
py_methods.push(
|
py_methods.push(
|
||||||
|
|
|
@ -21,7 +21,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: IntoPyObject
|
where S: IntoPyObject
|
||||||
{
|
{
|
||||||
type R = *mut ffi::PyObject;
|
type R = *mut ffi::PyObject;
|
||||||
|
@ -90,7 +90,7 @@ impl CallbackConverter<()> for UnitCallbackConverter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IterNextResultConverter;
|
/*pub struct IterNextResultConverter;
|
||||||
|
|
||||||
impl <T> CallbackConverter<Option<T>>
|
impl <T> CallbackConverter<Option<T>>
|
||||||
for IterNextResultConverter
|
for IterNextResultConverter
|
||||||
|
@ -112,7 +112,7 @@ impl <T> CallbackConverter<Option<T>>
|
||||||
fn error_value() -> *mut ffi::PyObject {
|
fn error_value() -> *mut ffi::PyObject {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub trait WrappingCastTo<T> {
|
pub trait WrappingCastTo<T> {
|
||||||
fn wrapping_cast(self) -> T;
|
fn wrapping_cast(self) -> T;
|
||||||
|
@ -250,7 +250,7 @@ pub unsafe fn cb_unary_unit<Slf, F>(location: &str, slf: *mut ffi::PyObject, f:
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cb_meth<F, R>(location: &str, f: F) -> *mut ffi::PyObject
|
pub unsafe fn cb_meth<F>(location: &str, f: F) -> *mut ffi::PyObject
|
||||||
where F: for<'p> FnOnce(Python<'p>) -> *mut ffi::PyObject,
|
where F: for<'p> FnOnce(Python<'p>) -> *mut ffi::PyObject,
|
||||||
F: panic::UnwindSafe
|
F: panic::UnwindSafe
|
||||||
{
|
{
|
||||||
|
@ -270,6 +270,26 @@ pub unsafe fn cb_meth<F, R>(location: &str, f: F) -> *mut ffi::PyObject
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cb_setter<F>(location: &str, f: F) -> c_int
|
||||||
|
where F: for<'p> FnOnce(Python<'p>) -> c_int,
|
||||||
|
F: panic::UnwindSafe
|
||||||
|
{
|
||||||
|
let guard = AbortOnDrop(location);
|
||||||
|
let ret = panic::catch_unwind(|| {
|
||||||
|
let py = Python::assume_gil_acquired();
|
||||||
|
f(py)
|
||||||
|
});
|
||||||
|
let ret = match ret {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(ref err) => {
|
||||||
|
handle_panic(Python::assume_gil_acquired(), err);
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mem::forget(guard);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::R
|
pub unsafe fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::R
|
||||||
where C: CallbackConverter<T>
|
where C: CallbackConverter<T>
|
||||||
|
|
|
@ -24,13 +24,13 @@ pub trait PyAsyncProtocol<'p>: PyTypeInfo + Sized + 'static {
|
||||||
fn __aiter__(&'p self, py: Python<'p>)
|
fn __aiter__(&'p self, py: Python<'p>)
|
||||||
-> Self::Result where Self: PyAsyncAiterProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyAsyncAiterProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __anext__(&'p self, py: Python<'p>)
|
fn __anext__(&'p mut self, py: Python<'p>)
|
||||||
-> Self::Result where Self: PyAsyncAnextProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyAsyncAnextProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __aenter__(&'p self, py: Python<'p>)
|
fn __aenter__(&'p mut self, py: Python<'p>)
|
||||||
-> Self::Result where Self: PyAsyncAenterProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyAsyncAenterProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __aexit__(&'p self, py: Python<'p>,
|
fn __aexit__(&'p mut self, py: Python<'p>,
|
||||||
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>)
|
||||||
|
|
|
@ -31,10 +31,10 @@ pub trait PyObjectProtocol<'p>: PyTypeInfo + Sized + 'static {
|
||||||
fn __getattr__(&'p self, py: Python<'p>, name: Self::Name)
|
fn __getattr__(&'p self, py: Python<'p>, name: Self::Name)
|
||||||
-> Self::Result where Self: PyObjectGetAttrProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyObjectGetAttrProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __setattr__(&'p self, py: Python<'p>, name: Self::Name, value: Self::Value)
|
fn __setattr__(&'p mut self, py: Python<'p>, name: Self::Name, value: Self::Value)
|
||||||
-> Self::Result where Self: PyObjectSetAttrProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyObjectSetAttrProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __delattr__(&'p self, py: Python<'p>, name: Self::Name)
|
fn __delattr__(&'p mut self, py: Python<'p>, name: Self::Name)
|
||||||
-> Self::Result where Self: PyObjectDelAttrProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyObjectDelAttrProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __str__(&'p self, py: Python<'p>)
|
fn __str__(&'p self, py: Python<'p>)
|
||||||
|
|
|
@ -16,10 +16,10 @@ use callback::PyObjectCallbackConverter;
|
||||||
/// Iterator protocol
|
/// Iterator protocol
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait PyIterProtocol<'p> : PyTypeInfo {
|
pub trait PyIterProtocol<'p> : PyTypeInfo {
|
||||||
fn __iter__(&'p self, py: Python<'p>)
|
fn __iter__(&'p mut self, py: Python<'p>)
|
||||||
-> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __next__(&'p self, py: Python<'p>)
|
fn __next__(&'p mut self, py: Python<'p>)
|
||||||
-> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ macro_rules! py_unary_func {
|
||||||
let ret = $crate::std::panic::catch_unwind(|| {
|
let ret = $crate::std::panic::catch_unwind(|| {
|
||||||
let py = $crate::Python::assume_gil_acquired();
|
let py = $crate::Python::assume_gil_acquired();
|
||||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||||
let res = slf.$f(py).into();
|
let res = slf.as_mut().$f(py).into();
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
|
@ -131,7 +131,7 @@ macro_rules! py_binary_func{
|
||||||
|
|
||||||
let result = match arg.extract() {
|
let result = match arg.extract() {
|
||||||
Ok(arg) => {
|
Ok(arg) => {
|
||||||
slf.$f(py, arg).into()
|
slf.as_mut().$f(py, arg).into()
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
};
|
};
|
||||||
|
@ -164,6 +164,56 @@ macro_rules! py_binary_func{
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! py_binary_self_func{
|
||||||
|
($trait:ident, $class:ident :: $f:ident) => {{
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
|
||||||
|
arg: *mut ffi::PyObject) -> *mut $crate::ffi::PyObject
|
||||||
|
where T: for<'p> $trait<'p>
|
||||||
|
{
|
||||||
|
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
|
||||||
|
|
||||||
|
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||||
|
let ret = $crate::std::panic::catch_unwind(|| {
|
||||||
|
let py = $crate::Python::assume_gil_acquired();
|
||||||
|
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||||
|
let arg = $crate::PyObject::from_borrowed_ptr(py, arg);
|
||||||
|
|
||||||
|
let result = match arg.extract() {
|
||||||
|
Ok(arg) => {
|
||||||
|
slf1.as_mut().$f(py, arg).into()
|
||||||
|
}
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
slf
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
e.restore(py);
|
||||||
|
$crate::std::ptr::null_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let ret = match ret {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(ref err) => {
|
||||||
|
$crate::callback::handle_panic($crate::Python::assume_gil_acquired(), err);
|
||||||
|
$crate::std::ptr::null_mut()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$crate::mem::forget(guard);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
Some(wrap::<$class>)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
macro_rules! py_ssizearg_func {
|
macro_rules! py_ssizearg_func {
|
||||||
|
@ -180,7 +230,7 @@ macro_rules! py_ssizearg_func {
|
||||||
let py = $crate::Python::assume_gil_acquired();
|
let py = $crate::Python::assume_gil_acquired();
|
||||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||||
|
|
||||||
let result = slf.$f(py, arg as isize).into();
|
let result = slf.as_mut().$f(py, arg as isize).into();
|
||||||
match result {
|
match result {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||||
|
@ -232,7 +282,7 @@ macro_rules! py_ternary_func{
|
||||||
|
|
||||||
let result = match arg1.extract() {
|
let result = match arg1.extract() {
|
||||||
Ok(arg1) => match arg2.extract() {
|
Ok(arg1) => match arg2.extract() {
|
||||||
Ok(arg2) => slf.$f(py, arg1, arg2).into(),
|
Ok(arg2) => slf.as_mut().$f(py, arg1, arg2).into(),
|
||||||
Err(e) => Err(e.into())
|
Err(e) => Err(e.into())
|
||||||
},
|
},
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
|
@ -268,6 +318,58 @@ macro_rules! py_ternary_func{
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! py_ternary_self_func{
|
||||||
|
($trait:ident, $class:ident :: $f:ident) => {{
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject,
|
||||||
|
arg1: *mut $crate::ffi::PyObject,
|
||||||
|
arg2: *mut $crate::ffi::PyObject)
|
||||||
|
-> *mut $crate::ffi::PyObject
|
||||||
|
where T: for<'p> $trait<'p>
|
||||||
|
{
|
||||||
|
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
|
||||||
|
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||||
|
let ret = $crate::std::panic::catch_unwind(|| {
|
||||||
|
let py = $crate::Python::assume_gil_acquired();
|
||||||
|
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||||
|
let arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
|
||||||
|
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
|
||||||
|
|
||||||
|
let result = match arg1.extract() {
|
||||||
|
Ok(arg1) => match arg2.extract() {
|
||||||
|
Ok(arg2) => slf1.as_mut().$f(py, arg1, arg2).into(),
|
||||||
|
Err(e) => Err(e.into())
|
||||||
|
},
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => slf,
|
||||||
|
Err(e) => {
|
||||||
|
e.restore(py);
|
||||||
|
$crate::std::ptr::null_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let ret = match ret {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(ref err) => {
|
||||||
|
$crate::callback::handle_panic(
|
||||||
|
$crate::Python::assume_gil_acquired(), err);
|
||||||
|
$crate::std::ptr::null_mut()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$crate::mem::forget(guard);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(wrap::<T>)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -336,7 +438,7 @@ macro_rules! py_func_del{
|
||||||
let name = PyObject::from_borrowed_ptr(py, name);
|
let name = PyObject::from_borrowed_ptr(py, name);
|
||||||
let result = match name.extract() {
|
let result = match name.extract() {
|
||||||
Ok(name) =>
|
Ok(name) =>
|
||||||
slf.$f(py, name).into(),
|
slf.as_mut().$f(py, name).into(),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
|
@ -394,7 +496,7 @@ macro_rules! py_func_set_del{
|
||||||
if value.is_null() {
|
if value.is_null() {
|
||||||
let result = match name.extract() {
|
let result = match name.extract() {
|
||||||
Ok(name) =>
|
Ok(name) =>
|
||||||
slf.$f2(py, name).into(),
|
slf.as_mut().$f2(py, name).into(),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
|
@ -410,7 +512,7 @@ macro_rules! py_func_set_del{
|
||||||
let result = match name.extract() {
|
let result = match name.extract() {
|
||||||
Ok(name) => match value.extract() {
|
Ok(name) => match value.extract() {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
slf.$f(py, name, value).into()
|
slf.as_mut().$f(py, name, value).into()
|
||||||
},
|
},
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,10 +23,10 @@ pub trait PyMappingProtocol<'p>: PyTypeInfo + Sized + 'static {
|
||||||
fn __getitem__(&'p self, py: Python<'p>, key: Self::Key)
|
fn __getitem__(&'p self, py: Python<'p>, key: Self::Key)
|
||||||
-> Self::Result where Self: PyMappingGetItemProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyMappingGetItemProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __setitem__(&'p self, py: Python<'p>, key: Self::Key, value: Self::Value)
|
fn __setitem__(&'p mut self, py: Python<'p>, key: Self::Key, value: Self::Value)
|
||||||
-> Self::Result where Self: PyMappingSetItemProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyMappingSetItemProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __delitem__(&'p self, py: Python<'p>, key: Self::Key)
|
fn __delitem__(&'p mut self, py: Python<'p>, key: Self::Key)
|
||||||
-> Self::Result where Self: PyMappingDelItemProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyMappingDelItemProtocol<'p> {unimplemented!()}
|
||||||
|
|
||||||
fn __iter__(&'p self, py: Python<'p>)
|
fn __iter__(&'p self, py: Python<'p>)
|
||||||
|
|
|
@ -74,31 +74,31 @@ pub trait PyNumberProtocol<'p>: PyTypeInfo {
|
||||||
fn __ror__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __ror__(&'p self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberROrProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberROrProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __iadd__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __iadd__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIAddProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIAddProtocol<'p> { unimplemented!() }
|
||||||
fn __isub__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __isub__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberISubProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberISubProtocol<'p> { unimplemented!() }
|
||||||
fn __imul__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __imul__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIMulProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIMulProtocol<'p> { unimplemented!() }
|
||||||
fn __imatmul__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __imatmul__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIMatmulProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIMatmulProtocol<'p> { unimplemented!() }
|
||||||
fn __itruediv__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __itruediv__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberITruedivProtocol<'p> {unimplemented!()}
|
-> Self::Result where Self: PyNumberITruedivProtocol<'p> {unimplemented!()}
|
||||||
fn __ifloordiv__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __ifloordiv__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIFloordivProtocol<'p> {unimplemented!() }
|
-> Self::Result where Self: PyNumberIFloordivProtocol<'p> {unimplemented!() }
|
||||||
fn __imod__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __imod__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIModProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIModProtocol<'p> { unimplemented!() }
|
||||||
fn __ipow__(&'p self, py: Python<'p>, other: Self::Other, modulo: Self::Modulo)
|
fn __ipow__(&'p mut self, py: Python<'p>, other: Self::Other, modulo: Self::Modulo)
|
||||||
-> Self::Result where Self: PyNumberIPowProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIPowProtocol<'p> { unimplemented!() }
|
||||||
fn __ilshift__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __ilshift__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberILShiftProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberILShiftProtocol<'p> { unimplemented!() }
|
||||||
fn __irshift__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __irshift__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIRShiftProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIRShiftProtocol<'p> { unimplemented!() }
|
||||||
fn __iand__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __iand__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIAndProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIAndProtocol<'p> { unimplemented!() }
|
||||||
fn __ixor__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __ixor__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIXorProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIXorProtocol<'p> { unimplemented!() }
|
||||||
fn __ior__(&'p self, py: Python<'p>, other: Self::Other)
|
fn __ior__(&'p mut self, py: Python<'p>, other: Self::Other)
|
||||||
-> Self::Result where Self: PyNumberIOrProtocol<'p> { unimplemented!() }
|
-> Self::Result where Self: PyNumberIOrProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
// Unary arithmetic
|
// Unary arithmetic
|
||||||
|
@ -124,12 +124,12 @@ pub trait PyNumberProtocol<'p>: PyTypeInfo {
|
||||||
|
|
||||||
|
|
||||||
pub trait PyNumberAddProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: for<'a> 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 PyNumberSubProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberSubProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: for<'a> FromPyObject<'a>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Success: ToPyObject;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
type Result: Into<PyResult<Self::Success>>;
|
||||||
}
|
}
|
||||||
|
@ -270,74 +270,60 @@ pub trait PyNumberROrProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
|
|
||||||
pub trait PyNumberIAddProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberISubProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberISubProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIMulProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberITruedivProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberITruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIModProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIModProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIPowProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIPowProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Modulo: FromPyObject<'p>;
|
type Modulo: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberILShiftProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberILShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIAndProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIXorProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
pub trait PyNumberIOrProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberIOrProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Other: FromPyObject<'p>;
|
type Other: FromPyObject<'p>;
|
||||||
type Success: ToPyObject;
|
type Result: Into<PyResult<()>>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PyNumberNegProtocol<'p>: PyNumberProtocol<'p> {
|
pub trait PyNumberNegProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
|
@ -689,8 +675,7 @@ impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIAddProtocolImpl for T where T: for<'p> PyNumberIAddProtocol<'p> {
|
impl<T> PyNumberIAddProtocolImpl for T where T: for<'p> PyNumberIAddProtocol<'p> {
|
||||||
fn nb_inplace_add() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_add() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIAddProtocol,
|
py_binary_self_func!(PyNumberIAddProtocol, T::__iadd__)
|
||||||
T::__iadd__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,8 +687,7 @@ impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberISubProtocolImpl for T where T: for<'p> PyNumberISubProtocol<'p> {
|
impl<T> PyNumberISubProtocolImpl for T where T: for<'p> PyNumberISubProtocol<'p> {
|
||||||
fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberISubProtocol,
|
py_binary_self_func!(PyNumberISubProtocol, T::__isub__)
|
||||||
T::__isub__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,8 +699,7 @@ impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIMulProtocolImpl for T where T: for<'p> PyNumberIMulProtocol<'p> {
|
impl<T> PyNumberIMulProtocolImpl for T where T: for<'p> PyNumberIMulProtocol<'p> {
|
||||||
fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIMulProtocol,
|
py_binary_self_func!(PyNumberIMulProtocol, T::__imul__)
|
||||||
T::__imul__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,8 +711,7 @@ impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIMatmulProtocolImpl for T where T: for<'p> PyNumberIMatmulProtocol<'p> {
|
impl<T> PyNumberIMatmulProtocolImpl for T where T: for<'p> PyNumberIMatmulProtocol<'p> {
|
||||||
fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIMatmulProtocol,
|
py_binary_self_func!(PyNumberIMatmulProtocol, T::__imatmul__)
|
||||||
T::__imatmul__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,8 +723,7 @@ impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberITruedivProtocolImpl for T where T: for<'p> PyNumberITruedivProtocol<'p> {
|
impl<T> PyNumberITruedivProtocolImpl for T where T: for<'p> PyNumberITruedivProtocol<'p> {
|
||||||
fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberITruedivProtocol,
|
py_binary_self_func!(PyNumberITruedivProtocol, T::__itruediv__)
|
||||||
T::__itruediv__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,8 +735,7 @@ impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIFloordivProtocolImpl for T where T: for<'p> PyNumberIFloordivProtocol<'p> {
|
impl<T> PyNumberIFloordivProtocolImpl for T where T: for<'p> PyNumberIFloordivProtocol<'p> {
|
||||||
fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIFloordivProtocol,
|
py_binary_self_func!(PyNumberIFloordivProtocol, T::__ifloordiv__)
|
||||||
T::__ifloordiv__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,8 +747,7 @@ impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIModProtocolImpl for T where T: for<'p> PyNumberIModProtocol<'p> {
|
impl<T> PyNumberIModProtocolImpl for T where T: for<'p> PyNumberIModProtocol<'p> {
|
||||||
fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIModProtocol,
|
py_binary_self_func!(PyNumberIModProtocol, T::__imod__)
|
||||||
T::__imod__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,8 +759,7 @@ impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIPowProtocolImpl for T where T: for<'p> PyNumberIPowProtocol<'p> {
|
impl<T> PyNumberIPowProtocolImpl for T where T: for<'p> PyNumberIPowProtocol<'p> {
|
||||||
fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
|
fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
|
||||||
py_ternary_func!(PyNumberIPowProtocol,
|
py_ternary_self_func!(PyNumberIPowProtocol, T::__ipow__)
|
||||||
T::__ipow__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,8 +771,7 @@ impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberILShiftProtocolImpl for T where T: for<'p> PyNumberILShiftProtocol<'p> {
|
impl<T> PyNumberILShiftProtocolImpl for T where T: for<'p> PyNumberILShiftProtocol<'p> {
|
||||||
fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberILShiftProtocol,
|
py_binary_self_func!(PyNumberILShiftProtocol, T::__ilshift__)
|
||||||
T::__ilshift__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,8 +783,7 @@ impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIRShiftProtocolImpl for T where T: for<'p> PyNumberIRShiftProtocol<'p> {
|
impl<T> PyNumberIRShiftProtocolImpl for T where T: for<'p> PyNumberIRShiftProtocol<'p> {
|
||||||
fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIRShiftProtocol,
|
py_binary_self_func!(PyNumberIRShiftProtocol, T::__irshift__)
|
||||||
T::__irshift__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,8 +796,7 @@ impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIAndProtocolImpl for T where T: for<'p> PyNumberIAndProtocol<'p> {
|
impl<T> PyNumberIAndProtocolImpl for T where T: for<'p> PyNumberIAndProtocol<'p> {
|
||||||
fn nb_inplace_and() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_and() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIAndProtocol,
|
py_binary_self_func!(PyNumberIAndProtocol, T::__iand__)
|
||||||
T::__iand__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,8 +808,7 @@ impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIXorProtocolImpl for T where T: for<'p> PyNumberIXorProtocol<'p> {
|
impl<T> PyNumberIXorProtocolImpl for T where T: for<'p> PyNumberIXorProtocol<'p> {
|
||||||
fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIXorProtocol,
|
py_binary_self_func!(PyNumberIXorProtocol, T::__ixor__)
|
||||||
T::__ixor__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,8 +820,7 @@ impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
|
||||||
}
|
}
|
||||||
impl<T> PyNumberIOrProtocolImpl for T where T: for<'p> PyNumberIOrProtocol<'p> {
|
impl<T> PyNumberIOrProtocolImpl for T where T: for<'p> PyNumberIOrProtocol<'p> {
|
||||||
fn nb_inplace_or() -> Option<ffi::binaryfunc> {
|
fn nb_inplace_or() -> Option<ffi::binaryfunc> {
|
||||||
py_binary_func!(PyNumberIOrProtocol,
|
py_binary_self_func!(PyNumberIOrProtocol, T::__ior__)
|
||||||
T::__ior__, T::Success, PyObjectCallbackConverter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ pub trait PySequenceProtocol<'p>: PyTypeInfo + Sized + 'static {
|
||||||
fn __getitem__(&'p self, py: Python<'p>, key: isize) -> Self::Result
|
fn __getitem__(&'p self, py: Python<'p>, key: isize) -> Self::Result
|
||||||
where Self: PySequenceGetItemProtocol<'p> { unimplemented!() }
|
where Self: PySequenceGetItemProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __setitem__(&'p self, py: Python<'p>, key: isize, value: Self::Value) -> Self::Result
|
fn __setitem__(&'p mut self, py: Python<'p>, key: isize, value: Self::Value) -> Self::Result
|
||||||
where Self: PySequenceSetItemProtocol<'p> { unimplemented!() }
|
where Self: PySequenceSetItemProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __delitem__(&'p self, py: Python<'p>, key: isize) -> Self::Result
|
fn __delitem__(&'p mut self, py: Python<'p>, key: isize) -> Self::Result
|
||||||
where Self: PySequenceDelItemProtocol<'p> { unimplemented!() }
|
where Self: PySequenceDelItemProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __contains__(&'p self, py: Python<'p>, item: Self::Item) -> Self::Result
|
fn __contains__(&'p self, py: Python<'p>, item: Self::Item) -> Self::Result
|
||||||
|
@ -38,10 +38,10 @@ pub trait PySequenceProtocol<'p>: PyTypeInfo + Sized + 'static {
|
||||||
fn __repeat__(&'p self, py: Python<'p>, count: isize) -> Self::Result
|
fn __repeat__(&'p self, py: Python<'p>, count: isize) -> Self::Result
|
||||||
where Self: PySequenceRepeatProtocol<'p> { unimplemented!() }
|
where Self: PySequenceRepeatProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __inplace_concat__(&'p self, py: Python<'p>, other: Self::Other) -> Self::Result
|
fn __inplace_concat__(&'p mut self, py: Python<'p>, other: Self::Other) -> Self::Result
|
||||||
where Self: PySequenceInplaceConcatProtocol<'p> { unimplemented!() }
|
where Self: PySequenceInplaceConcatProtocol<'p> { unimplemented!() }
|
||||||
|
|
||||||
fn __inplace_repeat__(&'p self, py: Python<'p>, count: isize) -> Self::Result
|
fn __inplace_repeat__(&'p mut self, py: Python<'p>, count: isize) -> Self::Result
|
||||||
where Self: PySequenceInplaceRepeatProtocol<'p> { unimplemented!() }
|
where Self: PySequenceInplaceRepeatProtocol<'p> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ pub trait IntoPyObject {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject>
|
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject>
|
||||||
where Self: Sized;
|
where Self: Sized;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +99,7 @@ impl <'p, T: ?Sized> RefFromPyObject<'p> for T
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default IntoPyObject implementation
|
// Default IntoPyObject implementation
|
||||||
impl <T> IntoPyObject for T where T: ToPyObject
|
impl<T> IntoPyObject for T where T: ToPyObject
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
|
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
|
||||||
|
@ -139,7 +138,7 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T> IntoPyObject for Option<T> where T: IntoPyObject {
|
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 {
|
||||||
|
|
|
@ -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::{AsPy, Python};
|
pub use python::{AsPy, Python, PythonToken};
|
||||||
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
|
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
|
||||||
pub use conversion::{FromPyObject, /*RefFromPyObject,*/ ToPyObject, IntoPyObject, 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::*;
|
||||||
|
|
|
@ -1,20 +1,6 @@
|
||||||
// Copyright (c) 2015 Daniel Grunwald
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
// software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
||||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
||||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or
|
|
||||||
// substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
||||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
@ -303,7 +289,6 @@ impl<T> fmt::Display for PyPtr<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std;
|
use std;
|
||||||
|
|
|
@ -22,22 +22,22 @@ macro_rules! pyobject_newtype(
|
||||||
|
|
||||||
impl<'p> $crate::python::AsPy<'p> for &'p $name {
|
impl<'p> $crate::python::AsPy<'p> for &'p $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn py<'a>(&'a self) -> Python<'p> {
|
fn py<'a>(&'a self) -> $crate::Python<'p> {
|
||||||
unsafe { $crate::python::Python::assume_gil_acquired() }
|
unsafe { $crate::python::Python::assume_gil_acquired() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::python::ToPythonPointer for $name {
|
impl $crate::python::ToPythonPointer for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||||
self as *const _ as *mut ffi::PyObject
|
self as *const _ as *mut $crate::ffi::PyObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> $crate::python::ToPythonPointer for &'a $name {
|
impl<'a> $crate::python::ToPythonPointer for &'a $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||||
self as *const _ as *mut ffi::PyObject
|
self as *const _ as *mut $crate::ffi::PyObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,32 @@ macro_rules! pyobject_newtype(
|
||||||
unsafe { &mut $crate::ffi::$typeobject }
|
unsafe { &mut $crate::ffi::$typeobject }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl $crate::std::fmt::Debug for $name {
|
||||||
|
default fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||||
|
-> Result<(), $crate::std::fmt::Error>
|
||||||
|
{
|
||||||
|
let py = unsafe { $crate::python::Python::assume_gil_acquired() };
|
||||||
|
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_nullptr(
|
||||||
|
py, $crate::ffi::PyObject_Repr(
|
||||||
|
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||||
|
let repr_obj = try!(s.map_err(|_| $crate::std::fmt::Error));
|
||||||
|
f.write_str(&repr_obj.to_string_lossy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::std::fmt::Display for $name {
|
||||||
|
fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||||
|
-> Result<(), $crate::std::fmt::Error>
|
||||||
|
{
|
||||||
|
let py = unsafe { $crate::python::Python::assume_gil_acquired() };
|
||||||
|
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_nullptr(
|
||||||
|
py, $crate::ffi::PyObject_Str(
|
||||||
|
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||||
|
let str_obj = try!(s.map_err(|_| $crate::std::fmt::Error));
|
||||||
|
f.write_str(&str_obj.to_string_lossy())
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
27
src/pyptr.rs
27
src/pyptr.rs
|
@ -20,6 +20,26 @@ pub struct PyPtr<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyPtr<T> {
|
impl<T> PyPtr<T> {
|
||||||
|
/// Creates a PyPtr instance for the given FFI pointer.
|
||||||
|
/// This moves ownership over the pointer into the Py.
|
||||||
|
/// Undefined behavior if the pointer is NULL or invalid.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn from_owned_ptr(ptr: *mut ffi::PyObject) -> PyPtr<T> {
|
||||||
|
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||||
|
PyPtr {inner: ptr, _t: PhantomData}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a PyPTr instance for the given FFI pointer.
|
||||||
|
/// Calls Py_INCREF() on the ptr.
|
||||||
|
/// Undefined behavior if the pointer is NULL or invalid.
|
||||||
|
/// Caller of this method has to have valid Py object.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn from_borrowed_ptr(ptr: *mut ffi::PyObject) -> PyPtr<T> {
|
||||||
|
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||||
|
ffi::Py_INCREF(ptr);
|
||||||
|
PyPtr {inner: ptr, _t: PhantomData}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_ref<'p>(&self, _py: Python<'p>) -> Py<'p, T> {
|
pub fn as_ref<'p>(&self, _py: Python<'p>) -> Py<'p, T> {
|
||||||
Py{inner: self.inner, _t: PhantomData, _py: PhantomData}
|
Py{inner: self.inner, _t: PhantomData, _py: PhantomData}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +76,6 @@ impl<T> IntoPythonPointer for PyPtr<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn into_ptr(self) -> *mut ffi::PyObject {
|
fn into_ptr(self) -> *mut ffi::PyObject {
|
||||||
println!("INTO PTR: {:?}", self.inner);
|
|
||||||
let ptr = self.inner;
|
let ptr = self.inner;
|
||||||
std::mem::forget(self);
|
std::mem::forget(self);
|
||||||
ptr
|
ptr
|
||||||
|
@ -206,7 +225,7 @@ impl<'p, T> Py<'p, T>
|
||||||
impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
||||||
{
|
{
|
||||||
/// Create new python object and move T instance under python management
|
/// Create new python object and move T instance under python management
|
||||||
pub fn new(py: &Python<'p>, value: T) -> PyResult<Py<'p, T>> where T: PyObjectAlloc<Type=T>
|
pub fn new(py: Python<'p>, value: T) -> PyResult<Py<'p, T>> where T: PyObjectAlloc<Type=T>
|
||||||
{
|
{
|
||||||
let ob = unsafe {
|
let ob = unsafe {
|
||||||
try!(<T as PyObjectAlloc>::alloc(py, value))
|
try!(<T as PyObjectAlloc>::alloc(py, value))
|
||||||
|
@ -463,10 +482,10 @@ impl <'a, T> ToPyObject for Py<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a, T> IntoPyObject for Py<'a, T> {
|
impl<'p, T> IntoPyObject for Py<'p, T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
|
default fn into_object<'a>(self, py: Python<'a>) -> Py<'a, PyObject> {
|
||||||
PyObject::from_borrowed_ptr(py, self.inner)
|
PyObject::from_borrowed_ptr(py, self.inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,6 @@
|
||||||
// Copyright (c) 2015 Daniel Grunwald
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
// software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
||||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
||||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or
|
|
||||||
// substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
||||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
use std;
|
use std;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -42,11 +28,19 @@ use pythonrun::GILGuard;
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Python<'p>(PhantomData<&'p GILGuard>);
|
pub struct Python<'p>(PhantomData<&'p GILGuard>);
|
||||||
|
|
||||||
|
pub struct PythonToken<T>(PhantomData<T>);
|
||||||
|
|
||||||
|
|
||||||
pub trait AsPy<'p> {
|
pub trait AsPy<'p> {
|
||||||
fn py<'a>(&'a self) -> Python<'p>;
|
fn py<'a>(&'a self) -> Python<'p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub trait PyClone : Sized {
|
||||||
|
fn clone_ref(&self) -> PyPtr<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||||
pub trait ToPythonPointer {
|
pub trait ToPythonPointer {
|
||||||
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
||||||
|
@ -55,7 +49,8 @@ pub trait ToPythonPointer {
|
||||||
|
|
||||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||||
pub trait IntoPythonPointer {
|
pub trait IntoPythonPointer {
|
||||||
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
/// Retrieves the underlying FFI pointer. Whether pointer owned or borrowed
|
||||||
|
/// depends on implementation.
|
||||||
fn into_ptr(self) -> *mut ffi::PyObject;
|
fn into_ptr(self) -> *mut ffi::PyObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +77,7 @@ impl <T> IntoPythonPointer for Option<T> where T: IntoPythonPointer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'p> Python<'p> {
|
impl<'p> Python<'p> {
|
||||||
/// Retrieve Python instance under the assumption that the GIL is already acquired at this point,
|
/// Retrieve Python instance under the assumption that the GIL is already acquired at this point,
|
||||||
/// and stays acquired for the lifetime `'p`.
|
/// and stays acquired for the lifetime `'p`.
|
||||||
|
@ -169,14 +165,6 @@ impl<'p> Python<'p> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new PyObject instance
|
|
||||||
#[inline]
|
|
||||||
pub fn init<T>(&'p self, value: T) -> Py<'p, T>
|
|
||||||
where T: PyTypeInfo + PyObjectAlloc<Type=T>
|
|
||||||
{
|
|
||||||
Py::new(self, value).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the Python builtin value `None`.
|
/// Gets the Python builtin value `None`.
|
||||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -219,8 +207,69 @@ impl<'p> Python<'p> {
|
||||||
pub fn import(self, name : &str) -> PyResult<Py<'p, PyModule>> {
|
pub fn import(self, name : &str) -> PyResult<Py<'p, PyModule>> {
|
||||||
PyModule::import(self, name)
|
PyModule::import(self, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_token<T, F>(self, f: F) -> Py<'p, T>
|
||||||
|
where F: FnOnce(PythonToken<T>) -> T,
|
||||||
|
T: PyTypeInfo + PyObjectAlloc<Type=T>
|
||||||
|
{
|
||||||
|
let value = f(PythonToken(PhantomData));
|
||||||
|
Py::new(self, value).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PythonToken<T> {
|
||||||
|
|
||||||
|
/// Gets the Python builtin value `None`.
|
||||||
|
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||||
|
#[inline]
|
||||||
|
pub fn None(self) -> PyPtr<PyObject> {
|
||||||
|
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_None()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the Python builtin value `True`.
|
||||||
|
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||||
|
#[inline]
|
||||||
|
pub fn True(self) -> PyPtr<PyBool> {
|
||||||
|
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_True()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the Python builtin value `False`.
|
||||||
|
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||||
|
#[inline]
|
||||||
|
pub fn False(self) -> PyPtr<PyBool> {
|
||||||
|
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_False()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the Python builtin value `NotImplemented`.
|
||||||
|
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||||
|
#[inline]
|
||||||
|
pub fn NotImplemented(self) -> PyPtr<PyObject> {
|
||||||
|
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_NotImplemented()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the Python type object for type T.
|
||||||
|
pub fn get_type<U>(self) -> PyPtr<PyType> where U: PyTypeObject {
|
||||||
|
U::type_object(Python(PhantomData)).into_pptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute closure `F` with Python instance.
|
||||||
|
/// Retrieve Python instance under the assumption that the GIL is already acquired
|
||||||
|
/// at this point, and stays acquired during closure call.
|
||||||
|
pub fn with_py<'p, F>(self, f: F) where F: FnOnce(Python<'p>)
|
||||||
|
{
|
||||||
|
f(Python(PhantomData))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_token<P, F>(self, f: F) -> PyPtr<P>
|
||||||
|
where F: FnOnce(PythonToken<P>) -> P,
|
||||||
|
P: PyTypeInfo + PyObjectAlloc<Type=P>
|
||||||
|
{
|
||||||
|
let value = f(PythonToken(PhantomData));
|
||||||
|
Py::new(Python(PhantomData), value).unwrap().into_pptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use {Python, PyDict};
|
use {Python, PyDict};
|
||||||
|
|
|
@ -92,12 +92,12 @@ pub trait PyObjectAlloc {
|
||||||
/// and initializes it using init_val.
|
/// and initializes it using init_val.
|
||||||
/// `ty` must be derived from the Self type, and the resulting object
|
/// `ty` must be derived from the Self type, and the resulting object
|
||||||
/// must be of type `ty`.
|
/// must be of type `ty`.
|
||||||
unsafe fn alloc(_py: &Python, value: Self::Type) -> PyResult<*mut ffi::PyObject>;
|
unsafe fn alloc(_py: Python, value: Self::Type) -> PyResult<*mut ffi::PyObject>;
|
||||||
|
|
||||||
/// Calls the rust destructor for the object and frees the memory
|
/// Calls the rust destructor for the object and frees the memory
|
||||||
/// (usually by calling ptr->ob_type->tp_free).
|
/// (usually by calling ptr->ob_type->tp_free).
|
||||||
/// This function is used as tp_dealloc implementation.
|
/// This function is used as tp_dealloc implementation.
|
||||||
unsafe fn dealloc(_py: &Python, obj: *mut ffi::PyObject);
|
unsafe fn dealloc(_py: Python, obj: *mut ffi::PyObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A PythonObject that is usable as a base type for #[class]
|
/// A PythonObject that is usable as a base type for #[class]
|
||||||
|
@ -108,7 +108,7 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
||||||
/// and initializes it using init_val.
|
/// and initializes it using init_val.
|
||||||
/// `ty` must be derived from the Self type, and the resulting object
|
/// `ty` must be derived from the Self type, and the resulting object
|
||||||
/// must be of type `ty`.
|
/// must be of type `ty`.
|
||||||
unsafe fn alloc(_py: &Python, value: T::Type) -> PyResult<*mut ffi::PyObject> {
|
unsafe fn alloc(_py: Python, value: T::Type) -> PyResult<*mut ffi::PyObject> {
|
||||||
let obj = ffi::PyType_GenericAlloc(
|
let obj = ffi::PyType_GenericAlloc(
|
||||||
<Self as PyTypeInfo>::type_object(), 0);
|
<Self as PyTypeInfo>::type_object(), 0);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
||||||
/// Calls the rust destructor for the object and frees the memory
|
/// Calls the rust destructor for the object and frees the memory
|
||||||
/// (usually by calling ptr->ob_type->tp_free).
|
/// (usually by calling ptr->ob_type->tp_free).
|
||||||
/// This function is used as tp_dealloc implementation.
|
/// This function is used as tp_dealloc implementation.
|
||||||
unsafe fn dealloc(_py: &Python, obj: *mut ffi::PyObject) {
|
unsafe fn dealloc(_py: Python, obj: *mut ffi::PyObject) {
|
||||||
let ptr = (obj as *mut u8).offset(
|
let ptr = (obj as *mut u8).offset(
|
||||||
<Self as PyTypeInfo>::offset() as isize) as *mut Self::Type;
|
<Self as PyTypeInfo>::offset() as isize) as *mut Self::Type;
|
||||||
std::ptr::drop_in_place(ptr);
|
std::ptr::drop_in_place(ptr);
|
||||||
|
@ -296,7 +296,7 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
|
||||||
println!("DEALLOC: {:?}", obj);
|
println!("DEALLOC: {:?}", obj);
|
||||||
let guard = AbortOnDrop("Cannot unwind out of tp_dealloc");
|
let guard = AbortOnDrop("Cannot unwind out of tp_dealloc");
|
||||||
let py = Python::assume_gil_acquired();
|
let py = Python::assume_gil_acquired();
|
||||||
let r = <T as PyObjectAlloc>::dealloc(&py, obj);
|
let r = <T as PyObjectAlloc>::dealloc(py, obj);
|
||||||
mem::forget(guard);
|
mem::forget(guard);
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
@ -329,24 +329,24 @@ fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
|
//for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
// defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
for def in <T as class::async::PyAsyncProtocolImpl>::methods() {
|
//for def in <T as class::async::PyAsyncProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
// defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
for def in <T as class::context::PyContextProtocolImpl>::methods() {
|
//for def in <T as class::context::PyContextProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
// defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
for def in <T as class::mapping::PyMappingProtocolImpl>::methods() {
|
//for def in <T as class::mapping::PyMappingProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
//defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
for def in <T as class::number::PyNumberProtocolImpl>::methods() {
|
//for def in <T as class::number::PyNumberProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
// defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
|
//for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
|
||||||
defs.push(def.as_method_def())
|
// defs.push(def.as_method_def())
|
||||||
}
|
//}
|
||||||
|
|
||||||
(new, call, defs)
|
(new, call, defs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ use std::cell::RefCell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use pyo3::ffi;
|
use pyo3::ffi;
|
||||||
|
use pyo3::python::ToPythonPointer;
|
||||||
|
|
||||||
|
|
||||||
macro_rules! py_run {
|
macro_rules! py_run {
|
||||||
($py:expr, $val:ident, $code:expr) => {{
|
($py:expr, $val:ident, $code:expr) => {{
|
||||||
|
@ -26,7 +28,7 @@ macro_rules! py_assert {
|
||||||
macro_rules! py_expect_exception {
|
macro_rules! py_expect_exception {
|
||||||
($py:expr, $val:ident, $code:expr, $err:ident) => {{
|
($py:expr, $val:ident, $code:expr, $err:ident) => {{
|
||||||
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();
|
||||||
let res = $py.run($code, None, Some(&d));
|
let res = $py.run($code, None, Some(&d));
|
||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
if !err.matches($py, $py.get_type::<exc::$err>()) {
|
if !err.matches($py, $py.get_type::<exc::$err>()) {
|
||||||
|
@ -71,7 +73,7 @@ struct EmptyClassWithNew { }
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl EmptyClassWithNew {
|
impl EmptyClassWithNew {
|
||||||
#[__new__]
|
#[__new__]
|
||||||
fn __new__(cls: &PyType) -> PyResult<EmptyClassWithNew> {
|
fn __new__(cls: &PyType, py: Python) -> PyResult<EmptyClassWithNew> {
|
||||||
Ok(EmptyClassWithNew{})
|
Ok(EmptyClassWithNew{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +93,7 @@ struct NewWithOneArg {
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl NewWithOneArg {
|
impl NewWithOneArg {
|
||||||
#[new]
|
#[new]
|
||||||
fn __new__(_cls: &PyType, arg: i32) -> PyResult<NewWithOneArg> {
|
fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult<NewWithOneArg> {
|
||||||
Ok(NewWithOneArg{_data: arg})
|
Ok(NewWithOneArg{_data: arg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +116,7 @@ struct NewWithTwoArgs {
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl NewWithTwoArgs {
|
impl NewWithTwoArgs {
|
||||||
#[new]
|
#[new]
|
||||||
fn __new__(_cls: &PyType, arg1: i32, arg2: i32) -> PyResult<NewWithTwoArgs> {
|
fn __new__(_cls: &PyType, py: Python, arg1: i32, arg2: i32) -> PyResult<NewWithTwoArgs> {
|
||||||
Ok(NewWithTwoArgs{_data1: arg1, _data2: arg2})
|
Ok(NewWithTwoArgs{_data1: arg1, _data2: arg2})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +171,7 @@ struct InstanceMethod {
|
||||||
|
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl InstanceMethod {
|
impl InstanceMethod {
|
||||||
fn method(&self) -> PyResult<i32> {
|
fn method(&self, py: Python) -> PyResult<i32> {
|
||||||
Ok(self.member)
|
Ok(self.member)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +182,7 @@ fn instance_method() {
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let obj = py.init(InstanceMethod{member: 42});
|
let obj = py.init(InstanceMethod{member: 42});
|
||||||
assert!(obj.method().unwrap() == 42);
|
assert!(obj.method(py).unwrap() == 42);
|
||||||
let d = PyDict::new(py);
|
let d = PyDict::new(py);
|
||||||
d.set_item("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();
|
||||||
|
@ -192,7 +194,7 @@ struct InstanceMethodWithArgs {
|
||||||
}
|
}
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl InstanceMethodWithArgs {
|
impl InstanceMethodWithArgs {
|
||||||
fn method(&self, multiplier: i32) -> PyResult<i32> {
|
fn method(&self, py: Python, multiplier: i32) -> PyResult<i32> {
|
||||||
Ok(self.member * multiplier)
|
Ok(self.member * multiplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +205,7 @@ fn instance_method_with_args() {
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let obj = py.init(InstanceMethodWithArgs{member: 7});
|
let obj = py.init(InstanceMethodWithArgs{member: 7});
|
||||||
assert!(obj.method(6).unwrap() == 42);
|
assert!(obj.method(py, 6).unwrap() == 42);
|
||||||
let d = PyDict::new(py);
|
let d = PyDict::new(py);
|
||||||
d.set_item("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();
|
||||||
|
@ -261,7 +263,7 @@ struct StaticMethod {}
|
||||||
impl StaticMethod {
|
impl StaticMethod {
|
||||||
#[new]
|
#[new]
|
||||||
fn __new__(cls: &PyType, py: Python) -> PyResult<StaticMethod> {
|
fn __new__(cls: &PyType, py: Python) -> PyResult<StaticMethod> {
|
||||||
StaticMethod::create_instance(py)
|
Ok(StaticMethod{}.into_object(py))
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[staticmethod]
|
//#[staticmethod]
|
||||||
|
@ -303,18 +305,18 @@ impl StaticMethod {
|
||||||
|
|
||||||
#[py::class]
|
#[py::class]
|
||||||
struct GCIntegration {
|
struct GCIntegration {
|
||||||
self_ref: RefCell<PyObject>,
|
self_ref: RefCell<PyPtr<PyObject>>,
|
||||||
dropped: TestDropCall,
|
dropped: TestDropCall,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyGCProtocol for GCIntegration {
|
impl PyGCProtocol for GCIntegration {
|
||||||
fn __traverse__(&self, py: Python, visit: PyVisit) -> Result<(), PyTraverseError> {
|
fn __traverse__(&self, py: Python, visit: PyVisit) -> Result<(), PyTraverseError> {
|
||||||
visit.call(&*self.self_ref(py).borrow())
|
visit.call(&*self.self_ref.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __clear__(&self, py: Python) {
|
fn __clear__(&mut self, py: Python) {
|
||||||
let old_ref = mem::replace(&mut *self.self_ref(py).borrow_mut(), py.None());
|
let old_ref = mem::replace(&mut *self.self_ref.borrow_mut(), py.None());
|
||||||
// Release reference only after the mutable borrow has expired.
|
// Release reference only after the mutable borrow has expired.
|
||||||
old_ref.release_ref(py);
|
old_ref.release_ref(py);
|
||||||
}
|
}
|
||||||
|
@ -326,12 +328,12 @@ fn gc_integration() {
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let drop_called = Arc::new(AtomicBool::new(false));
|
let drop_called = Arc::new(AtomicBool::new(false));
|
||||||
let inst = GCIntegration::create_instance(py,
|
let inst = py.init(GCIntegration{
|
||||||
RefCell::new(py.None()),
|
self_ref: RefCell::new(py.None()),
|
||||||
TestDropCall { drop_called: drop_called.clone() }
|
dropped: TestDropCall { drop_called: drop_called.clone() }});
|
||||||
).unwrap();
|
|
||||||
*inst.self_ref(py).borrow_mut() = inst.as_object().clone_ref(py);
|
*inst.self_ref.borrow_mut() = inst.clone_ref().into_object().into_pptr();
|
||||||
inst.release_ref(py);
|
drop(inst);
|
||||||
|
|
||||||
py.run("import gc; gc.collect()", None, None).unwrap();
|
py.run("import gc; gc.collect()", None, None).unwrap();
|
||||||
assert!(drop_called.load(Ordering::Relaxed));
|
assert!(drop_called.load(Ordering::Relaxed));
|
||||||
|
@ -345,7 +347,7 @@ pub struct Len {
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyMappingProtocol for Len {
|
impl PyMappingProtocol for Len {
|
||||||
fn __len__(&self, py: Python) -> PyResult<usize> {
|
fn __len__(&self, py: Python) -> PyResult<usize> {
|
||||||
Ok(*self.l(py))
|
Ok(self.l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,14 +356,14 @@ fn len() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let inst = Len::create_instance(py, 10).unwrap();
|
let inst = Len{l: 10}.into_object(py);
|
||||||
py_assert!(py, inst, "len(inst) == 10");
|
py_assert!(py, inst, "len(inst) == 10");
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_eq!(ffi::PyObject_Size(inst.as_object().as_ptr()), 10);
|
assert_eq!(ffi::PyObject_Size(inst.as_ptr()), 10);
|
||||||
assert_eq!(ffi::PyMapping_Size(inst.as_object().as_ptr()), 10);
|
assert_eq!(ffi::PyMapping_Size(inst.as_ptr()), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inst = Len::create_instance(py, (isize::MAX as usize) + 1).unwrap();
|
let inst = Len{l: (isize::MAX as usize) + 1}.into_object(py);
|
||||||
py_expect_exception!(py, inst, "len(inst)", OverflowError);
|
py_expect_exception!(py, inst, "len(inst)", OverflowError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,16 +393,16 @@ fn iterator() {
|
||||||
struct StringMethods {}
|
struct StringMethods {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for StringMethods {
|
impl<'p> PyObjectProtocol<'p> for StringMethods {
|
||||||
fn __str__(&self) -> PyResult<&'static str> {
|
fn __str__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("str")
|
Ok("str")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __repr__(&self) -> PyResult<&'static str> {
|
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("repr")
|
Ok("repr")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __format__(&self, format_spec: String) -> PyResult<String> {
|
fn __format__(&self, py: Python, format_spec: String) -> PyResult<String> {
|
||||||
Ok(format!("format({})", format_spec))
|
Ok(format!("format({})", format_spec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +410,7 @@ impl PyObjectProtocol for StringMethods {
|
||||||
// Ok(PyString::new(py, "unicode"))
|
// Ok(PyString::new(py, "unicode"))
|
||||||
//}
|
//}
|
||||||
|
|
||||||
fn __bytes__(&self) -> PyResult<PyBytes> {
|
fn __bytes__(&self, py: Python) -> PyResult<Py<PyBytes>> {
|
||||||
Ok(PyBytes::new(py, b"bytes"))
|
Ok(PyBytes::new(py, b"bytes"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +420,7 @@ fn string_methods() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let obj = StringMethods::create_instance(py).unwrap();
|
let obj = StringMethods{}.into_object(py);
|
||||||
py_assert!(py, obj, "str(obj) == 'str'");
|
py_assert!(py, obj, "str(obj) == 'str'");
|
||||||
py_assert!(py, obj, "repr(obj) == 'repr'");
|
py_assert!(py, obj, "repr(obj) == 'repr'");
|
||||||
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
|
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
|
||||||
|
@ -433,12 +435,12 @@ struct Comparisons {
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for Comparisons {
|
impl PyObjectProtocol for Comparisons {
|
||||||
fn __hash__(&self) -> PyResult<usize> {
|
fn __hash__(&self, py: Python) -> PyResult<usize> {
|
||||||
Ok(*self.val(py) as usize)
|
Ok(self.val as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __bool__(&self) -> PyResult<bool> {
|
fn __bool__(&self, py: Python) -> PyResult<bool> {
|
||||||
Ok(*self.val(py) != 0)
|
Ok(self.val != 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,10 +450,10 @@ fn comparisons() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let zero = Comparisons::create_instance(py, 0).unwrap();
|
let zero = Comparisons{val: 0}.into_object(py);
|
||||||
let one = Comparisons::create_instance(py, 1).unwrap();
|
let one = Comparisons{val: 1}.into_object(py);
|
||||||
let ten = Comparisons::create_instance(py, 10).unwrap();
|
let ten = Comparisons{val: 10}.into_object(py);
|
||||||
let minus_one = Comparisons::create_instance(py, -1).unwrap();
|
let minus_one = Comparisons{val: -1}.into_object(py);
|
||||||
py_assert!(py, one, "hash(one) == 1");
|
py_assert!(py, one, "hash(one) == 1");
|
||||||
py_assert!(py, ten, "hash(ten) == 10");
|
py_assert!(py, ten, "hash(ten) == 10");
|
||||||
py_assert!(py, minus_one, "hash(minus_one) == -2");
|
py_assert!(py, minus_one, "hash(minus_one) == -2");
|
||||||
|
@ -466,11 +468,11 @@ struct Sequence {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PySequenceProtocol for Sequence {
|
impl PySequenceProtocol for Sequence {
|
||||||
fn __len__(&self) -> PyResult<usize> {
|
fn __len__(&self, py: Python) -> PyResult<usize> {
|
||||||
Ok(5)
|
Ok(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __getitem__(&self, key: isize) -> PyResult<isize> {
|
fn __getitem__(&self, py: Python, 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));
|
||||||
}
|
}
|
||||||
|
@ -483,7 +485,7 @@ fn sequence() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = Sequence::create_instance(py).unwrap();
|
let c = Sequence{}.into_object(py);
|
||||||
py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]");
|
py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]");
|
||||||
py_expect_exception!(py, c, "c['abc']", TypeError);
|
py_expect_exception!(py, c, "c['abc']", TypeError);
|
||||||
}
|
}
|
||||||
|
@ -496,7 +498,7 @@ struct Callable {}
|
||||||
impl Callable {
|
impl Callable {
|
||||||
|
|
||||||
#[__call__]
|
#[__call__]
|
||||||
fn __call__(&self, arg: i32) -> PyResult<i32> {
|
fn __call__(&self, py: Python, arg: i32) -> PyResult<i32> {
|
||||||
Ok(arg * 6)
|
Ok(arg * 6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,11 +508,11 @@ fn callable() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = Callable::create_instance(py).unwrap();
|
let c = Callable{}.into_object(py);
|
||||||
py_assert!(py, c, "callable(c)");
|
py_assert!(py, c, "callable(c)");
|
||||||
py_assert!(py, c, "c(7) == 42");
|
py_assert!(py, c, "c(7) == 42");
|
||||||
|
|
||||||
let nc = Comparisons::create_instance(py, 0).unwrap();
|
let nc = Comparisons{val: 0}.into_object(py);
|
||||||
py_assert!(py, nc, "not callable(nc)");
|
py_assert!(py, nc, "not callable(nc)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,9 +524,9 @@ struct SetItem {
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyMappingProtocol<'a> for SetItem {
|
impl PyMappingProtocol<'a> for SetItem {
|
||||||
fn __setitem__(&self, key: i32, val: i32) -> PyResult<()> {
|
fn __setitem__(&mut self, py: Python, key: i32, val: i32) -> PyResult<()> {
|
||||||
*self.key_mut(py) = key;
|
self.key = key;
|
||||||
*self.val_mut(py) = val;
|
self.val = val;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,7 +536,7 @@ 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(0, 0).unwrap();
|
let c = py.init(SetItem{key: 0, val: 0});
|
||||||
py_run!(py, c, "c[1] = 2");
|
py_run!(py, c, "c[1] = 2");
|
||||||
assert_eq!(c.key, 1);
|
assert_eq!(c.key, 1);
|
||||||
assert_eq!(c.val, 2);
|
assert_eq!(c.val, 2);
|
||||||
|
@ -548,8 +550,8 @@ struct DelItem {
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyMappingProtocol<'a> for DelItem {
|
impl PyMappingProtocol<'a> for DelItem {
|
||||||
fn __delitem__(&self, key: i32) -> PyResult<()> {
|
fn __delitem__(&mut self, py: Python, key: i32) -> PyResult<()> {
|
||||||
*self.key_mut(py) = key;
|
self.key = key;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,9 +561,9 @@ fn delitem() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = DelItem::create_instance(py, 0).unwrap();
|
let c = py.init(DelItem{key:0});
|
||||||
py_run!(py, c, "del c[1]");
|
py_run!(py, c, "del c[1]");
|
||||||
assert_eq!(*c.key(py), 1);
|
assert_eq!(c.key, 1);
|
||||||
py_expect_exception!(py, c, "c[1] = 2", NotImplementedError);
|
py_expect_exception!(py, c, "c[1] = 2", NotImplementedError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,13 +574,13 @@ struct SetDelItem {
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyMappingProtocol for SetDelItem {
|
impl PyMappingProtocol for SetDelItem {
|
||||||
fn __setitem__(&self, key: i32, val: i32) -> PyResult<()> {
|
fn __setitem__(&mut self, py: Python, key: i32, val: i32) -> PyResult<()> {
|
||||||
*self.val_mut(py) = Some(val);
|
self.val = Some(val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __delitem__(&self, key: i32) -> PyResult<()> {
|
fn __delitem__(&mut self, py: Python, key: i32) -> PyResult<()> {
|
||||||
*self.val_mut(py) = None;
|
self.val = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,11 +590,11 @@ fn setdelitem() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = SetDelItem::create_instance(py, None).unwrap();
|
let c = py.init(SetDelItem{val: None});
|
||||||
py_run!(py, c, "c[1] = 2");
|
py_run!(py, c, "c[1] = 2");
|
||||||
assert_eq!(*c.val(py), Some(2));
|
assert_eq!(c.val, Some(2));
|
||||||
py_run!(py, c, "del c[1]");
|
py_run!(py, c, "del c[1]");
|
||||||
assert_eq!(*c.val(py), None);
|
assert_eq!(c.val, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[py::class]
|
#[py::class]
|
||||||
|
@ -600,7 +602,7 @@ struct Reversed {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyMappingProtocol for Reversed{
|
impl PyMappingProtocol for Reversed{
|
||||||
fn __reversed__(&self) -> PyResult<&'static str> {
|
fn __reversed__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
println!("__reversed__");
|
println!("__reversed__");
|
||||||
Ok("I am reversed")
|
Ok("I am reversed")
|
||||||
}
|
}
|
||||||
|
@ -611,7 +613,7 @@ fn reversed() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = Reversed::create_instance(py).unwrap();
|
let c = Reversed{}.into_object(py);
|
||||||
py_run!(py, c, "assert reversed(c) == 'I am reversed'");
|
py_run!(py, c, "assert reversed(c) == 'I am reversed'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +622,7 @@ struct Contains {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PySequenceProtocol for Contains {
|
impl PySequenceProtocol for Contains {
|
||||||
fn __contains__(&self, item: i32) -> PyResult<bool> {
|
fn __contains__(&self, py: Python, item: i32) -> PyResult<bool> {
|
||||||
Ok(item >= 0)
|
Ok(item >= 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,7 +632,7 @@ fn contains() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = Contains::create_instance(py).unwrap();
|
let c = Contains{}.into_object(py);
|
||||||
py_run!(py, c, "assert 1 in c");
|
py_run!(py, c, "assert 1 in c");
|
||||||
py_run!(py, c, "assert -1 not in c");
|
py_run!(py, c, "assert -1 not in c");
|
||||||
py_expect_exception!(py, c, "assert 'wrong type' not in c", TypeError);
|
py_expect_exception!(py, c, "assert 'wrong type' not in c", TypeError);
|
||||||
|
@ -644,19 +646,19 @@ struct UnaryArithmetic {}
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyNumberProtocol for UnaryArithmetic {
|
impl PyNumberProtocol for UnaryArithmetic {
|
||||||
|
|
||||||
fn __neg__(&self) -> PyResult<&'static str> {
|
fn __neg__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("neg")
|
Ok("neg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __pos__(&self) -> PyResult<&'static str> {
|
fn __pos__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("pos")
|
Ok("pos")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __abs__(&self) -> PyResult<&'static str> {
|
fn __abs__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("abs")
|
Ok("abs")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __invert__(&self) -> PyResult<&'static str> {
|
fn __invert__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("invert")
|
Ok("invert")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,7 +668,7 @@ fn unary_arithmetic() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = UnaryArithmetic::create_instance(py).unwrap();
|
let c = UnaryArithmetic{}.into_object(py);
|
||||||
py_run!(py, c, "assert -c == 'neg'");
|
py_run!(py, c, "assert -c == 'neg'");
|
||||||
py_run!(py, c, "assert +c == 'pos'");
|
py_run!(py, c, "assert +c == 'pos'");
|
||||||
py_run!(py, c, "assert abs(c) == 'abs'");
|
py_run!(py, c, "assert abs(c) == 'abs'");
|
||||||
|
@ -679,43 +681,43 @@ struct BinaryArithmetic {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for BinaryArithmetic {
|
impl PyObjectProtocol for BinaryArithmetic {
|
||||||
fn __repr__(&self) -> PyResult<&'static str> {
|
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("BA")
|
Ok("BA")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyNumberProtocol for BinaryArithmetic {
|
impl PyNumberProtocol for BinaryArithmetic {
|
||||||
fn __add__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __add__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} + {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} + {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __sub__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __sub__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} - {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} - {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __mul__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __mul__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} * {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} * {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __lshift__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __lshift__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} << {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} << {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __rshift__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __rshift__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} >> {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} >> {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __and__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __and__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} & {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} & {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __xor__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __xor__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} ^ {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} ^ {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __or__(&self, rhs: PyObject) -> PyResult<String> {
|
fn __or__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||||
Ok(format!("{:?} | {:?}", self.as_object(), rhs))
|
Ok(format!("{:?} | {:?}", self, rhs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,7 +726,7 @@ fn binary_arithmetic() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = BinaryArithmetic::create_instance(py).unwrap();
|
let c = BinaryArithmetic{}.into_object(py);
|
||||||
py_run!(py, c, "assert c + c == 'BA + BA'");
|
py_run!(py, c, "assert c + c == 'BA + BA'");
|
||||||
py_run!(py, c, "assert c + 1 == 'BA + 1'");
|
py_run!(py, c, "assert c + 1 == 'BA + 1'");
|
||||||
py_run!(py, c, "assert 1 + c == '1 + BA'");
|
py_run!(py, c, "assert 1 + c == '1 + BA'");
|
||||||
|
@ -751,35 +753,38 @@ struct RichComparisons {}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for RichComparisons {
|
impl PyObjectProtocol for RichComparisons {
|
||||||
fn __repr__(&self) -> PyResult<&'static str> {
|
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("RC")
|
Ok("RC")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<String> {
|
fn __richcmp__(&self, py: Python, other: &PyObject, op: CompareOp) -> PyResult<String> {
|
||||||
match op {
|
match op {
|
||||||
CompareOp::Lt => Ok(format!("{:?} < {:?}", self.as_object(), other)),
|
CompareOp::Lt => Ok(format!("{:?} < {:?}", self.__repr__(py), other)),
|
||||||
CompareOp::Le => Ok(format!("{:?} <= {:?}", self.as_object(), other)),
|
CompareOp::Le => Ok(format!("{:?} <= {:?}", self.__repr__(py), other)),
|
||||||
CompareOp::Eq => Ok(format!("{:?} == {:?}", self.as_object(), other)),
|
CompareOp::Eq => Ok(format!("{:?} == {:?}", self.__repr__(py), other)),
|
||||||
CompareOp::Ne => Ok(format!("{:?} != {:?}", self.as_object(), other)),
|
CompareOp::Ne => Ok(format!("{:?} != {:?}", self.__repr__(py), other)),
|
||||||
CompareOp::Gt => Ok(format!("{:?} > {:?}", self.as_object(), other)),
|
CompareOp::Gt => Ok(format!("{:?} > {:?}", self.__repr__(py), other)),
|
||||||
CompareOp::Ge => Ok(format!("{:?} >= {:?}", self.as_object(), other))
|
CompareOp::Ge => Ok(format!("{:?} >= {:?}", self.__repr__(py), other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[py::class]
|
#[py::class]
|
||||||
struct RichComparisons2 {}
|
struct RichComparisons2 {
|
||||||
|
py: PythonToken<RichComparisons2>
|
||||||
|
}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for RichComparisons2 {
|
impl PyObjectProtocol for RichComparisons2 {
|
||||||
fn __repr__(&self) -> PyResult<&'static str> {
|
fn __repr__(&self, py: Python) -> PyResult<&'static str> {
|
||||||
Ok("RC2")
|
Ok("RC2")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<PyObject> {
|
fn __richcmp__(&self, py: Python,
|
||||||
|
other: &PyObject, op: CompareOp) -> PyResult<Py<PyObject>> {
|
||||||
match op {
|
match op {
|
||||||
CompareOp::Eq => Ok(true.to_py_object(py).into_object()),
|
CompareOp::Eq => Ok(true.to_object(py).into_object()),
|
||||||
CompareOp::Ne => Ok(false.to_py_object(py).into_object()),
|
CompareOp::Ne => Ok(false.to_object(py).into_object()),
|
||||||
_ => Ok(py.NotImplemented())
|
_ => Ok(py.NotImplemented())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -790,7 +795,7 @@ fn rich_comparisons() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = RichComparisons::create_instance(py).unwrap();
|
let c = RichComparisons{}.into_object(py);
|
||||||
py_run!(py, c, "assert (c < c) == 'RC < RC'");
|
py_run!(py, c, "assert (c < c) == 'RC < RC'");
|
||||||
py_run!(py, c, "assert (c < 1) == 'RC < 1'");
|
py_run!(py, c, "assert (c < 1) == 'RC < 1'");
|
||||||
py_run!(py, c, "assert (1 < c) == 'RC > 1'");
|
py_run!(py, c, "assert (1 < c) == 'RC > 1'");
|
||||||
|
@ -816,7 +821,7 @@ fn rich_comparisons_python_3_type_error() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c2 = RichComparisons2::create_instance(py).unwrap();
|
let c2 = RichComparisons2{}.into_object(py);
|
||||||
py_expect_exception!(py, c2, "c2 < c2", TypeError);
|
py_expect_exception!(py, c2, "c2 < c2", TypeError);
|
||||||
py_expect_exception!(py, c2, "c2 < 1", TypeError);
|
py_expect_exception!(py, c2, "c2 < 1", TypeError);
|
||||||
py_expect_exception!(py, c2, "1 < c2", TypeError);
|
py_expect_exception!(py, c2, "1 < c2", TypeError);
|
||||||
|
@ -844,51 +849,51 @@ struct InPlaceOperations {
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyObjectProtocol for InPlaceOperations {
|
impl PyObjectProtocol for InPlaceOperations {
|
||||||
fn __repr__(&self) -> PyResult<String> {
|
fn __repr__(&self, py: Python) -> PyResult<String> {
|
||||||
Ok(format!("IPO({:?})", self.value(py)))
|
Ok(format!("IPO({:?})", self.value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl PyNumberProtocol for InPlaceOperations {
|
impl PyNumberProtocol for InPlaceOperations {
|
||||||
fn __iadd__(&self, other: u32) -> PyResult<Self> {
|
fn __iadd__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) + other;
|
self.value = self.value + other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __isub__(&self, other: u32) -> PyResult<Self> {
|
fn __isub__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) - other;
|
self.value = self.value - other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __imul__(&self, other: u32) -> PyResult<Self> {
|
fn __imul__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) * other;
|
self.value = self.value * other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __ilshift__(&self, other: u32) -> PyResult<Self> {
|
fn __ilshift__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) << other;
|
self.value = self.value << other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __irshift__(&self, other: u32) -> PyResult<Self> {
|
fn __irshift__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) >> other;
|
self.value = self.value >> other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __iand__(&self, other: u32) -> PyResult<Self> {
|
fn __iand__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) & other;
|
self.value = self.value & other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __ixor__(&self, other: u32) -> PyResult<Self> {
|
fn __ixor__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) ^ other;
|
self.value = self.value ^ other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __ior__(&self, other: u32) -> PyResult<Self> {
|
fn __ior__(&mut self, py: Python, other: u32) -> PyResult<()> {
|
||||||
*self.value_mut(py) = *self.value(py) | other;
|
self.value = self.value | other;
|
||||||
Ok(self.clone_ref(py))
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,28 +902,28 @@ fn inplace_operations() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 0).unwrap();
|
let c = InPlaceOperations{value: 0}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 10).unwrap();
|
let c = InPlaceOperations{value:10}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 3).unwrap();
|
let c = InPlaceOperations{value: 3}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 3).unwrap();
|
let c = InPlaceOperations{value: 3}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 12).unwrap();
|
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 12).unwrap();
|
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 12).unwrap();
|
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
||||||
|
|
||||||
let c = InPlaceOperations::create_instance(py, 12).unwrap();
|
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||||
py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,11 +935,11 @@ struct ContextManager {
|
||||||
#[py::proto]
|
#[py::proto]
|
||||||
impl<'p> PyContextProtocol<'p> for ContextManager {
|
impl<'p> PyContextProtocol<'p> for ContextManager {
|
||||||
|
|
||||||
fn __enter__(&self) -> PyResult<i32> {
|
fn __enter__(&mut self, py: Python) -> PyResult<i32> {
|
||||||
Ok(42)
|
Ok(42)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __exit__(&mut self,
|
fn __exit__(&mut self, py: Python,
|
||||||
ty: Option<&'p PyType>,
|
ty: Option<&'p PyType>,
|
||||||
value: Option<&'p PyObject>,
|
value: Option<&'p PyObject>,
|
||||||
traceback: Option<&'p PyObject>) -> PyResult<bool> {
|
traceback: Option<&'p PyObject>) -> PyResult<bool> {
|
||||||
|
@ -952,17 +957,19 @@ fn context_manager() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let c = ContextManager::create_instance(py, false).unwrap();
|
let c = py.init(ContextManager{exit_called: false});
|
||||||
py_run!(py, c, "with c as x:\n assert x == 42");
|
py_run!(py, c, "with c as x:\n assert x == 42");
|
||||||
assert!(*c.exit_called(py));
|
assert!(c.exit_called);
|
||||||
|
|
||||||
*c.exit_called_mut(py) = false;
|
c.exit_called = false;
|
||||||
py_run!(py, c, "with c as x:\n raise ValueError");
|
py_run!(py, c, "with c as x:\n raise ValueError");
|
||||||
assert!(*c.exit_called(py));
|
assert!(c.exit_called);
|
||||||
|
|
||||||
*c.exit_called_mut(py) = false;
|
c.exit_called = false;
|
||||||
py_expect_exception!(py, c, "with c as x:\n raise NotImplementedError", NotImplementedError);
|
py_expect_exception!(
|
||||||
assert!(*c.exit_called(py));
|
py, c, "with c as x:\n raise NotImplementedError",
|
||||||
|
NotImplementedError);
|
||||||
|
assert!(c.exit_called);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -974,17 +981,17 @@ struct ClassWithProperties {
|
||||||
#[py::methods]
|
#[py::methods]
|
||||||
impl ClassWithProperties {
|
impl ClassWithProperties {
|
||||||
|
|
||||||
fn get_num(&self) -> PyResult<i32> {
|
fn get_num(&self, py: Python) -> PyResult<i32> {
|
||||||
Ok(*self.num(py))
|
Ok(self.num)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[getter(DATA)]
|
#[getter(DATA)]
|
||||||
fn get_data(&self) -> PyResult<i32> {
|
fn get_data(&self, py: Python) -> PyResult<i32> {
|
||||||
Ok(*self.num(py))
|
Ok(self.num)
|
||||||
}
|
}
|
||||||
#[setter(DATA)]
|
#[setter(DATA)]
|
||||||
fn set(&self, value: i32) -> PyResult<()> {
|
fn set(&self, py: Python, value: i32) -> PyResult<()> {
|
||||||
*self.num_mut(py) = value;
|
self.num = value;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -995,7 +1002,7 @@ fn class_with_properties() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
let py = gil.python();
|
let py = gil.python();
|
||||||
|
|
||||||
let inst = ClassWithProperties::create_instance(py, 10).unwrap();
|
let inst = ClassWithProperties{num: 10}.into_object(py);
|
||||||
|
|
||||||
py_run!(py, inst, "assert inst.get_num() == 10");
|
py_run!(py, inst, "assert inst.get_num() == 10");
|
||||||
py_run!(py, inst, "assert inst.get_num() == inst.DATA");
|
py_run!(py, inst, "assert inst.get_num() == inst.DATA");
|
||||||
|
|
Loading…
Reference in a new issue