This commit is contained in:
konstin 2018-09-09 00:19:55 +02:00
parent 3724095048
commit d92e522243
9 changed files with 58 additions and 34 deletions

View File

@ -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]

View File

@ -5,15 +5,11 @@ description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
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"] }

View File

@ -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(),
)
}

View File

@ -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()) }
}
}

View File

@ -5,8 +5,7 @@ description = "Proc macros for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
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" }

View File

@ -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!(

View File

@ -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<ffi::objobjargproc> {
py_func_del!(
PyMappingDelItemProtocol,
Self,
__delitem__
)
py_func_del!(PyMappingDelItemProtocol, Self, __delitem__)
}
}

View File

@ -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))
}};
}

View File

@ -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<PyUsize> {
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");
}