From e85db971f9e4c350e2c002fc6eacbbb92d638380 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Thu, 15 Jun 2017 14:20:30 -0700 Subject: [PATCH] fix module export functions --- README.md | 5 ++--- pyo3cls/src/module.rs | 7 +++++-- src/lib.rs | 10 ++++++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 56dfd0a7..07763c35 100644 --- a/README.md +++ b/README.md @@ -86,9 +86,8 @@ fn init_mod(py: Python, m: &PyModule) -> PyResult<()> { m.add(py, "__doc__", "This module is implemented in Rust.")?; #[pyfn(m, "sum_as_string")] - // pyo3 aware function. All of our python interface could be - // declared in a separate module. - // Note that the py_fn!() macro automatically converts the arguments from + // pyo3 aware function. All of our python interface could be declared in a separate module. + // Note that the `#[pyfn()]` annotation automatically converts the arguments from // Python objects to Rust values; and the Rust return value back into a Python object. fn sum_as_string_py(_: Python, a:i64, b:i64) -> PyResult { let out = sum_as_string(a, b); diff --git a/pyo3cls/src/module.rs b/pyo3cls/src/module.rs index a2483ff2..6049c40a 100644 --- a/pyo3cls/src/module.rs +++ b/pyo3cls/src/module.rs @@ -281,12 +281,13 @@ fn wrap_fn(item: &mut syn::Item) -> Option> { ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(wrap), ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS, ml_doc: #doc, - }.as_method_def(); + }; unsafe { let func = pyo3::PyObject::from_owned_ptr_or_panic( py, pyo3::ffi::PyCFunction_New( - &def as *const _ as *mut _, std::ptr::null_mut())); + Box::into_raw(Box::new(def.as_method_def())), + std::ptr::null_mut())); std::mem::forget(def); #m.add(py, stringify!(#fnname), func)? @@ -335,6 +336,8 @@ pub fn impl_wrap(name: &syn::Ident, spec: &method::FnSpec) -> Tokens { let result: #output = { #body }; + py.release(kwargs); + py.release(args); _pyo3::callback::cb_convert( _pyo3::callback::PyObjectCallbackConverter, py, result) }) diff --git a/src/lib.rs b/src/lib.rs index f32dd94d..8db528f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,10 +68,10 @@ //! for adding the module's members. //! //! To creates a Python callable object that invokes a Rust function, specify rust -//! function and decroate it with `#[pyfn()]` attribute. `pyfn()` accepts three parameters. +//! function and decorate it with `#[pyfn()]` attribute. `pyfn()` accepts three parameters. //! //! 1. `m`: The module name. -//! 2. function name, name of function visible to Python code. +//! 2. name of function visible to Python code. //! 3. arguments description string, i.e. "param1, param2=None, *, param3=55" //! //! @@ -83,10 +83,16 @@ //! extern crate pyo3; //! use pyo3::{py, Python, PyResult, PyObject, PyModule, PyString}; //! +//! // add bindings to the generated python module +//! // N.B: names: "libhello" must be the name of the `.so` or `.pyd` file //! #[py::modinit(hello)] //! fn init_module(py: Python, m: &PyModule) -> PyResult<()> { //! m.add(py, "__doc__", "Module documentation string")?; //! +//! // pyo3 aware function. All of our python interface could be declared +//! // in a separate module. +//! // Note that the `#[pyfn()]` annotation automatically converts the arguments from +//! // Python objects to Rust values; and the Rust return value back into a Python object. //! #[pyfn(m, "run_rust_func")] //! fn run(py: Python, name: PyString) -> PyResult { //! println!("Rust says: Hello {} of Python!", name);