fix #[prop] impl

This commit is contained in:
Nikolay Kim 2017-08-07 23:52:24 -07:00
parent 59d9f9e453
commit 3b00145040
5 changed files with 33 additions and 9 deletions

View File

@ -348,7 +348,7 @@ fn impl_descriptors(cls: &syn::Ty, descriptors: Vec<(syn::Field, Vec<FnType>)>)
let tokens = quote! {
#(#methods)*
impl _pyo3::class::methods::PyMethodsProtocolImpl for #cls {
impl _pyo3::class::methods::PyPropMethodsProtocolImpl for #cls {
fn py_methods() -> &'static [_pyo3::class::PyMethodDefType] {
static METHODS: &'static [_pyo3::class::PyMethodDefType] = &[
#(#py_methods),*

View File

@ -9,6 +9,7 @@ static NO_PY_METHODS: &'static [PyMethodDefType] = &[];
/// `PyMethodDefType` represents different types of python callable objects.
/// It is used by `#[py::methods]` and `#[py::proto]` annotations.
#[derive(Debug)]
pub enum PyMethodDefType {
/// Represents class `__new__` method
New(PyMethodDef),
@ -28,7 +29,7 @@ pub enum PyMethodDefType {
Setter(PySetterDef),
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub enum PyMethodType {
PyCFunction(ffi::PyCFunction),
PyCFunctionWithKeywords(ffi::PyCFunctionWithKeywords),
@ -37,7 +38,7 @@ pub enum PyMethodType {
PyInitFunc(ffi::initproc),
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct PyMethodDef {
pub ml_name: &'static str,
pub ml_meth: PyMethodType,
@ -45,14 +46,14 @@ pub struct PyMethodDef {
pub ml_doc: &'static str,
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct PyGetterDef {
pub name: &'static str,
pub meth: ffi::getter,
pub doc: &'static str,
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct PySetterDef {
pub name: &'static str,
pub meth: ffi::setter,
@ -133,3 +134,14 @@ impl<T> PyMethodsProtocolImpl for T {
NO_PY_METHODS
}
}
#[doc(hidden)]
pub trait PyPropMethodsProtocolImpl {
fn py_methods() -> &'static [PyMethodDefType];
}
impl<T> PyPropMethodsProtocolImpl for T {
default fn py_methods() -> &'static [PyMethodDefType] {
NO_PY_METHODS
}
}

View File

@ -291,6 +291,8 @@ mod test {
#[test]
fn test_owned_nested() {
pythonrun::prepare_pyo3_library();
let gil = Python::acquire_gil();
let py = gil.python();
unsafe {
let p: &'static mut ReleasePool = &mut *POOL;
@ -298,8 +300,7 @@ mod test {
let cnt;
let empty;
{
let gil = Python::acquire_gil();
let py = gil.python();
let _pool = GILPool::new();
assert_eq!(p.owned.len(), 0);
// empty tuple is singleton
@ -318,7 +319,6 @@ mod test {
assert_eq!(p.owned.len(), 1);
}
{
let _gil = Python::acquire_gil();
assert_eq!(p.owned.len(), 0);
assert_eq!(cnt, ffi::Py_REFCNT(empty));
}

View File

@ -390,6 +390,8 @@ fn py_class_method_defs<T>() -> PyResult<(Option<ffi::newfunc>,
let mut new = None;
let mut init = None;
//<T as class::methods::PyPropMethodsProtocolImpl>::py_methods()
for def in <T as class::methods::PyMethodsProtocolImpl>::py_methods() {
match *def {
PyMethodDefType::New(ref def) => {
@ -458,7 +460,9 @@ fn py_class_async_methods<T>(_defs: &mut Vec<ffi::PyMethodDef>) {}
fn py_class_properties<T>() -> Vec<ffi::PyGetSetDef> {
let mut defs = HashMap::new();
for def in <T as class::methods::PyMethodsProtocolImpl>::py_methods() {
for def in <T as class::methods::PyMethodsProtocolImpl>::py_methods()
.iter().chain(<T as class::methods::PyPropMethodsProtocolImpl>::py_methods().iter())
{
match *def {
PyMethodDefType::Getter(ref getter) => {
let name = getter.name.to_string();

View File

@ -1288,6 +1288,14 @@ struct GetterSetter {
token: PyToken
}
#[py::methods]
impl GetterSetter {
fn get_num2(&self) -> PyResult<i32> {
Ok(self.num)
}
}
#[test]
fn getter_setter_autogen() {
let gil = Python::acquire_gil();