Fix py_module_initializer

This commit is contained in:
Daniel Grunwald 2015-04-18 01:52:48 +02:00
parent 2a91b00abe
commit 60360fa03f
4 changed files with 38 additions and 40 deletions

View File

@ -207,6 +207,18 @@ pub unsafe fn result_from_owned_ptr(py : Python, p : *mut ffi::PyObject) -> PyRe
}
}
/// Construct PyObject from the result of a python FFI call that returns a borrowed reference.
/// Returns Err(PyErr) if the pointer is null.
/// Unsafe because the pointer might be invalid.
#[inline]
pub unsafe fn result_from_borrowed_ptr(py : Python, p : *mut ffi::PyObject) -> PyResult<PyObject> {
if p.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(PyObject::from_borrowed_ptr(py, p))
}
}
pub unsafe fn result_cast_from_owned_ptr<'p, T>(py : Python<'p>, p : *mut ffi::PyObject) -> PyResult<'p, T>
where T: ::python::PythonObjectWithCheckedDowncast<'p>
{

View File

@ -39,7 +39,7 @@ macro_rules! py_module_initializer {
#[no_mangle]
pub extern "C" fn $init_funcname() {
let py = unsafe { $crate::Python::assume_gil_acquired() };
match $crate::PyModule::init(py, cstr!($name), $init) {
match $crate::PyModule::_init(py, cstr!($name), $init) {
Ok(()) => (),
Err(e) => e.restore()
}

View File

@ -10,12 +10,30 @@ use std::ffi::CStr;
pyobject_newtype!(PyModule, PyModule_Check, PyModule_Type);
impl <'p> PyModule<'p> {
/// Create a new module object with the __name__ attribute set to name.
/// Only the modules __doc__ and __name__ attributes are filled in;
/// the caller is responsible for providing a __file__ attribute.
pub fn new(py: Python<'p>, name: &CStr) -> PyResult<'p, PyModule<'p>> {
unsafe {
err::result_cast_from_owned_ptr(py, ffi::PyModule_New(name.as_ptr()))
}
}
/// Import the python module with the specified name.
pub fn import(py: Python<'p>, name: &CStr) -> PyResult<'p, PyModule<'p>> {
let result = try!(unsafe {
err::result_from_owned_ptr(py, ffi::PyImport_ImportModule(name.as_ptr()))
unsafe {
err::result_cast_from_owned_ptr(py, ffi::PyImport_ImportModule(name.as_ptr()))
}
}
// Helper method for module_initializer!() macro, do not use directly!
pub fn _init<F, R>(py: Python<'p>, name: &CStr, init: F) -> PyResult<'p, R>
where F: FnOnce(Python<'p>, PyModule<'p>) -> PyResult<'p, R> {
let module = try!(unsafe {
err::result_from_borrowed_ptr(py, ffi::Py_InitModule(name.as_ptr(), std::ptr::null_mut()))
});
Ok(try!(result.cast_into()))
let module = try!(module.cast_into::<PyModule>());
init(py, module)
}
/// Return the dictionary object that implements modules namespace;
@ -50,15 +68,6 @@ impl <'p> PyModule<'p> {
unsafe { self.str_from_ptr(ffi::PyModule_GetFilename(self.as_ptr())) }
}
pub fn init<F, R>(py: Python<'p>, name: &CStr, init: F) -> PyResult<'p, R>
where F: FnOnce(Python<'p>, PyModule<'p>) -> PyResult<'p, R> {
let module = try!(unsafe {
err::result_from_owned_ptr(py, ffi::Py_InitModule(name.as_ptr(), std::ptr::null_mut()))
});
let module = try!(module.cast_into::<PyModule>());
init(py, module)
}
/// Adds a member to the module.
/// This is a convenience function which can be used from the module's initialization function.
pub fn add<V>(&self, name: &CStr, value: V) -> PyResult<'p, ()> where V: ToPyObject<'p> {

View File

@ -1,37 +1,14 @@
#![crate_type = "dylib"]
#[macro_use] extern crate cpython;
extern crate "python27-sys" as py27;
//extern crate libc;
use cpython::{PyModule, PyResult, Python};
/*
py_module_initializer!("testmodule", inittestmodule, |py, m| {
println!("in initializer");
//try!(m.add(cstr!("__doc__"), "Module documentation string"));
//try!(m.add(cstr!("__author__"), "Daniel Grunwald"));
//try!(m.add(cstr!("__version__"), "0.0.1"));
Ok(())
});
*/
#[no_mangle]
pub extern "C" fn inittestmodule() {
//abort_on_panic!({
let py = unsafe { Python::assume_gil_acquired() };
if let Err(e) = init(py) {
println!("Restore error");
e.restore()
}
//})
}
fn init(py : Python) -> PyResult<()> {
let m : &PyModule = try!(py.init_module("testmodule", None));
//unsafe { py27::Py_InitModule(cstr!("testmodule").as_ptr(), std::ptr::null_mut()) };
println!("init_module done");
try!(m.add(cstr!("__doc__"), "Module documentation string"));
try!(m.add(cstr!("__author__"), "Daniel Grunwald"));
try!(m.add(cstr!("__version__"), "0.0.1"));
Ok(())
}
});