diff --git a/pyo3cls/src/py_class.rs b/pyo3cls/src/py_class.rs index be268791..55671de0 100644 --- a/pyo3cls/src/py_class.rs +++ b/pyo3cls/src/py_class.rs @@ -348,7 +348,7 @@ fn impl_descriptors(cls: &syn::Ty, descriptors: Vec<(syn::Field, Vec)>) 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),* diff --git a/src/class/methods.rs b/src/class/methods.rs index 9ecf66e2..2ed71f53 100644 --- a/src/class/methods.rs +++ b/src/class/methods.rs @@ -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 PyMethodsProtocolImpl for T { NO_PY_METHODS } } + +#[doc(hidden)] +pub trait PyPropMethodsProtocolImpl { + fn py_methods() -> &'static [PyMethodDefType]; +} + +impl PyPropMethodsProtocolImpl for T { + default fn py_methods() -> &'static [PyMethodDefType] { + NO_PY_METHODS + } +} diff --git a/src/pythonrun.rs b/src/pythonrun.rs index 70dc88ab..bee1e1b8 100644 --- a/src/pythonrun.rs +++ b/src/pythonrun.rs @@ -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)); } diff --git a/src/typeob.rs b/src/typeob.rs index ab73b39f..b041bd7b 100644 --- a/src/typeob.rs +++ b/src/typeob.rs @@ -390,6 +390,8 @@ fn py_class_method_defs() -> PyResult<(Option, let mut new = None; let mut init = None; + //::py_methods() + for def in ::py_methods() { match *def { PyMethodDefType::New(ref def) => { @@ -458,7 +460,9 @@ fn py_class_async_methods(_defs: &mut Vec) {} fn py_class_properties() -> Vec { let mut defs = HashMap::new(); - for def in ::py_methods() { + for def in ::py_methods() + .iter().chain(::py_methods().iter()) + { match *def { PyMethodDefType::Getter(ref getter) => { let name = getter.name.to_string(); diff --git a/tests/test_class.rs b/tests/test_class.rs index bb0159e6..427a4cda 100644 --- a/tests/test_class.rs +++ b/tests/test_class.rs @@ -1288,6 +1288,14 @@ struct GetterSetter { token: PyToken } +#[py::methods] +impl GetterSetter { + + fn get_num2(&self) -> PyResult { + Ok(self.num) + } +} + #[test] fn getter_setter_autogen() { let gil = Python::acquire_gil();