diff --git a/Cargo.toml b/Cargo.toml index 4521bea9..339944ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ mashup = "0.1.7" docmatic = "0.1.2" [build-dependencies] -regex = "1.0.4" +regex = "1.0.5" version_check = "0.1.4" [features] diff --git a/pyo3-derive-backend/Cargo.toml b/pyo3-derive-backend/Cargo.toml index f430aafb..7835c27b 100644 --- a/pyo3-derive-backend/Cargo.toml +++ b/pyo3-derive-backend/Cargo.toml @@ -5,15 +5,11 @@ description = "Code generation for PyO3 package" authors = ["PyO3 Project and Contributors "] keywords = ["pyo3", "python", "cpython", "ffi"] homepage = "https://github.com/pyo3/pyo3" -repository = "https://github.com/pyo3/pyo3.git" -documentation = "https://pyo3.github.io/pyo3/guide/" +repository = "https://github.com/pyo3/pyo3" categories = ["api-bindings", "development-tools::ffi"] license = "Apache-2.0" [dependencies] -quote = "0.6.6" -proc-macro2 = "0.4.13" - -[dependencies.syn-next] -version = "0.15.0-rc" -features = ["full", "extra-traits"] +quote = "0.6.8" +proc-macro2 = "0.4.18" +syn = { version = "0.15.1", features = ["full", "extra-traits"] } diff --git a/pyo3-derive-backend/src/module.rs b/pyo3-derive-backend/src/module.rs index 090ef8cf..2386b8f9 100644 --- a/pyo3-derive-backend/src/module.rs +++ b/pyo3-derive-backend/src/module.rs @@ -202,7 +202,10 @@ fn function_wrapper_ident(name: &syn::Ident) -> syn::Ident { // Make sure this ident matches the one of wrap_function // The trim_left_matches("r#") is for https://github.com/dtolnay/syn/issues/478 syn::Ident::new( - &format!("__pyo3_get_function_{}", name.to_string().trim_left_matches("r#")), + &format!( + "__pyo3_get_function_{}", + name.to_string().trim_left_matches("r#") + ), Span::call_site(), ) } diff --git a/pyo3-derive-backend/src/py_class.rs b/pyo3-derive-backend/src/py_class.rs index fc0d02f0..27c510c6 100644 --- a/pyo3-derive-backend/src/py_class.rs +++ b/pyo3-derive-backend/src/py_class.rs @@ -229,13 +229,13 @@ fn impl_class( // but for now it works and it only safe code and it is required to return custom // objects, so for now I'm keeping it impl ::pyo3::IntoPyObject for #cls { - fn into_object<'p>(self, py: ::pyo3::Python<'p>) -> ::pyo3::PyObject { + fn into_object(self, py: ::pyo3::Python) -> ::pyo3::PyObject { ::pyo3::Py::new(py, |_| self).unwrap().into_object(py) } } impl ::pyo3::ToPyObject for #cls { - fn to_object<'p>(&self, py: ::pyo3::Python<'p>) -> ::pyo3::PyObject { + fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject { unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } @@ -250,7 +250,7 @@ fn impl_class( } impl<'a> ::pyo3::ToPyObject for &'a mut #cls { - fn to_object<'p>(&self, py: ::pyo3::Python<'p>) -> ::pyo3::PyObject { + fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject { unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } diff --git a/pyo3cls/Cargo.toml b/pyo3cls/Cargo.toml index 52f74b28..020f1835 100644 --- a/pyo3cls/Cargo.toml +++ b/pyo3cls/Cargo.toml @@ -5,8 +5,7 @@ description = "Proc macros for PyO3 package" authors = ["PyO3 Project and Contributors "] keywords = ["pyo3", "python", "cpython", "ffi"] homepage = "https://github.com/pyo3/pyo3" -repository = "https://github.com/pyo3/pyo3.git" -documentation = "https://docs.rs/pyo3cls" +repository = "https://github.com/pyo3/pyo3" categories = ["api-bindings", "development-tools::ffi"] license = "Apache-2.0" @@ -14,13 +13,7 @@ license = "Apache-2.0" proc-macro = true [dependencies] -quote= "0.6.6" -proc-macro2 = "0.4.13" - -[dependencies.syn-next] -version= "0.15.0-rc" -features=["full", "extra-traits"] - -[dependencies.pyo3-derive-backend] -path = "../pyo3-derive-backend" -version = "=0.5.0" +quote= "0.6.8" +proc-macro2 = "0.4.18" +syn = { version = "0.15.1", features = ["full", "extra-traits"] } +pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.5.0" } diff --git a/pyo3cls/src/lib.rs b/pyo3cls/src/lib.rs index 145d5a9e..96c085dd 100644 --- a/pyo3cls/src/lib.rs +++ b/pyo3cls/src/lib.rs @@ -12,10 +12,10 @@ extern crate quote; #[macro_use] extern crate syn; +use proc_macro2::Span; use pyo3_derive_backend::*; use syn::parse::Parser; use syn::punctuated::Punctuated; -use proc_macro2::Span; #[proc_macro_attribute] pub fn mod2init( @@ -143,7 +143,10 @@ pub fn pyfunction( let mut ast: syn::ItemFn = syn::parse(input).expect("#[function] must be used on a `fn` block"); // Workaround for https://github.com/dtolnay/syn/issues/478 - let python_name = syn::Ident::new(&ast.ident.to_string().trim_left_matches("r#"), Span::call_site()); + let python_name = syn::Ident::new( + &ast.ident.to_string().trim_left_matches("r#"), + Span::call_site(), + ); let expanded = module::add_fn_to_module(&mut ast, &python_name, Vec::new()); quote!( diff --git a/src/class/mapping.rs b/src/class/mapping.rs index ff01698e..5ce4dc2f 100644 --- a/src/class/mapping.rs +++ b/src/class/mapping.rs @@ -225,11 +225,7 @@ impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {} /// Returns `py_func_set_del` if PyMappingSetItemProtocol is implemented, otherwise `py_func_del` trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> { fn det_set_dispatch() -> Option { - py_func_del!( - PyMappingDelItemProtocol, - Self, - __delitem__ - ) + py_func_del!(PyMappingDelItemProtocol, Self, __delitem__) } } diff --git a/tests/common.rs b/tests/common.rs index 84f0f7bf..20edc1ad 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -27,8 +27,14 @@ macro_rules! py_run { let d = PyDict::new($py); d.set_item(stringify!($val), &$val).unwrap(); $py.run(&common::indoc($code), None, Some(d)) - .map_err(|e| e.print($py)) - .expect(&common::indoc($code)) + .map_err(|e| { + e.print($py); + // So when this c api function the last line called printed the error to stderr, + // the output is only written into a buffer which is never flushed because we + // panic before flushing. This is where this hack comes into place + $py.run("import sys; sys.stderr.flush()", None, None) + .unwrap(); + }).expect(&common::indoc($code)) }}; } diff --git a/tests/test_various.rs b/tests/test_various.rs index 9eea3e95..c1a1c058 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -1,5 +1,6 @@ #![feature(specialization)] +#[macro_use] extern crate pyo3; use pyo3::prelude::*; @@ -39,3 +40,29 @@ fn mut_ref_arg() { py.run("inst1.set_other(inst2)", None, Some(d)).unwrap(); assert_eq!(inst2.as_ref(py).n, 100); } + +#[pyclass] +struct PyUsize { + #[prop(get)] + pub value: usize, +} + +#[pyfunction] +fn get_zero() -> PyResult { + Ok(PyUsize { value: 0 }) +} + +#[test] +/// Checks that we can use return a custom class in arbitrary function and use those functions +/// both in rust and python +fn return_custom_class() { + let gil = Python::acquire_gil(); + let py = gil.python(); + + // Using from rust + assert_eq!(get_zero().unwrap().value, 0); + + // Using from python + let get_zero = wrap_function!(get_zero)(py); + py_assert!(py, get_zero, "get_zero().value == 0"); +}