pymodule: tidy up module init
This commit is contained in:
parent
b3946c3f78
commit
355bd0c336
|
@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
- Remove pyclass implementation details from `PyTypeInfo`:
|
- Remove pyclass implementation details from `PyTypeInfo`:
|
||||||
- `Type`, `DESCRIPTION`, and `FLAGS` [#1456](https://github.com/PyO3/pyo3/pull/1456)
|
- `Type`, `DESCRIPTION`, and `FLAGS` [#1456](https://github.com/PyO3/pyo3/pull/1456)
|
||||||
- `BaseType`, `BaseLayout`, `Layout`, `Initializer` [#1596](https://github.com/PyO3/pyo3/pull/1596)
|
- `BaseType`, `BaseLayout`, `Layout`, `Initializer` [#1596](https://github.com/PyO3/pyo3/pull/1596)
|
||||||
|
- `PyModuleDef_INIT` [#1630](https://github.com/PyO3/pyo3/pull/1630)
|
||||||
- Remove `__doc__` from module's `__all__`. [#1509](https://github.com/PyO3/pyo3/pull/1509)
|
- Remove `__doc__` from module's `__all__`. [#1509](https://github.com/PyO3/pyo3/pull/1509)
|
||||||
- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. [#1521](https://github.com/PyO3/pyo3/pull/1521)
|
- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. [#1521](https://github.com/PyO3/pyo3/pull/1521)
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,11 @@ pub fn py_init(fnname: &Ident, name: &Ident, doc: syn::LitStr) -> TokenStream {
|
||||||
/// the module.
|
/// the module.
|
||||||
pub unsafe extern "C" fn #cb_name() -> *mut pyo3::ffi::PyObject {
|
pub unsafe extern "C" fn #cb_name() -> *mut pyo3::ffi::PyObject {
|
||||||
use pyo3::derive_utils::ModuleDef;
|
use pyo3::derive_utils::ModuleDef;
|
||||||
const NAME: &'static str = concat!(stringify!(#name), "\0");
|
static NAME: &str = concat!(stringify!(#name), "\0");
|
||||||
static MODULE_DEF: ModuleDef = unsafe { ModuleDef::new(NAME) };
|
static DOC: &str = concat!(#doc, "\0");
|
||||||
|
static MODULE_DEF: ModuleDef = unsafe { ModuleDef::new(NAME, DOC) };
|
||||||
|
|
||||||
pyo3::callback::handle_panic(|_py| { MODULE_DEF.make_module(#doc, #fnname) })
|
pyo3::callback::handle_panic(|_py| { MODULE_DEF.make_module(_py, #fnname) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::exceptions::PyTypeError;
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::pyclass::PyClass;
|
use crate::pyclass::PyClass;
|
||||||
use crate::types::{PyAny, PyDict, PyModule, PyString, PyTuple};
|
use crate::types::{PyAny, PyDict, PyModule, PyString, PyTuple};
|
||||||
use crate::{ffi, GILPool, PyCell, Python};
|
use crate::{ffi, PyCell, Python};
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -281,7 +281,6 @@ pub fn argument_extraction_error(py: Python, arg_name: &str, error: PyErr) -> Py
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `Sync` wrapper of `ffi::PyModuleDef`.
|
/// `Sync` wrapper of `ffi::PyModuleDef`.
|
||||||
#[doc(hidden)]
|
|
||||||
pub struct ModuleDef(UnsafeCell<ffi::PyModuleDef>);
|
pub struct ModuleDef(UnsafeCell<ffi::PyModuleDef>);
|
||||||
|
|
||||||
unsafe impl Sync for ModuleDef {}
|
unsafe impl Sync for ModuleDef {}
|
||||||
|
@ -291,19 +290,29 @@ impl ModuleDef {
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// `name` must be a null-terminated string.
|
/// `name` must be a null-terminated string.
|
||||||
pub const unsafe fn new(name: &'static str) -> Self {
|
pub const unsafe fn new(name: &'static str, doc: &'static str) -> Self {
|
||||||
#[allow(deprecated)]
|
const INIT: ffi::PyModuleDef = ffi::PyModuleDef {
|
||||||
let mut init = ffi::PyModuleDef_INIT;
|
m_base: ffi::PyModuleDef_HEAD_INIT,
|
||||||
init.m_name = name.as_ptr() as *const _;
|
m_name: std::ptr::null(),
|
||||||
ModuleDef(UnsafeCell::new(init))
|
m_doc: std::ptr::null(),
|
||||||
|
m_size: 0,
|
||||||
|
m_methods: std::ptr::null_mut(),
|
||||||
|
m_slots: std::ptr::null_mut(),
|
||||||
|
m_traverse: None,
|
||||||
|
m_clear: None,
|
||||||
|
m_free: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
ModuleDef(UnsafeCell::new(ffi::PyModuleDef {
|
||||||
|
m_name: name.as_ptr() as *const _,
|
||||||
|
m_doc: doc.as_ptr() as *const _,
|
||||||
|
..INIT
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
/// Builds a module using user given initializer. Used for `#[pymodule]`.
|
/// Builds a module using user given initializer. Used for `#[pymodule]`.
|
||||||
///
|
pub fn make_module(
|
||||||
/// # Safety
|
|
||||||
/// The caller must have GIL.
|
|
||||||
pub unsafe fn make_module(
|
|
||||||
&'static self,
|
&'static self,
|
||||||
doc: &str,
|
py: Python,
|
||||||
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
|
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
|
||||||
) -> PyResult<*mut ffi::PyObject> {
|
) -> PyResult<*mut ffi::PyObject> {
|
||||||
#[cfg(py_sys_config = "WITH_THREAD")]
|
#[cfg(py_sys_config = "WITH_THREAD")]
|
||||||
|
@ -312,14 +321,8 @@ impl ModuleDef {
|
||||||
#[cfg(not(Py_3_7))]
|
#[cfg(not(Py_3_7))]
|
||||||
ffi::PyEval_InitThreads();
|
ffi::PyEval_InitThreads();
|
||||||
|
|
||||||
let module = ffi::PyModule_Create(self.0.get());
|
let module =
|
||||||
let pool = GILPool::new();
|
unsafe { py.from_owned_ptr_or_err::<PyModule>(ffi::PyModule_Create(self.0.get()))? };
|
||||||
let py = pool.python();
|
|
||||||
if module.is_null() {
|
|
||||||
return Err(crate::PyErr::fetch(py));
|
|
||||||
}
|
|
||||||
let module = py.from_owned_ptr_or_err::<PyModule>(module)?;
|
|
||||||
module.setattr("__doc__", doc)?;
|
|
||||||
initializer(py, module)?;
|
initializer(py, module)?;
|
||||||
Ok(crate::IntoPyPointer::into_ptr(module))
|
Ok(crate::IntoPyPointer::into_ptr(module))
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,19 +90,3 @@ pub struct PyModuleDef {
|
||||||
pub m_clear: Option<inquiry>,
|
pub m_clear: Option<inquiry>,
|
||||||
pub m_free: Option<freefunc>,
|
pub m_free: Option<freefunc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper initial value of [`PyModuleDef`] for a Python class.
|
|
||||||
///
|
|
||||||
/// Not present in the Python C API.
|
|
||||||
#[deprecated(note = "not present in Python headers; to be removed")]
|
|
||||||
pub const PyModuleDef_INIT: PyModuleDef = PyModuleDef {
|
|
||||||
m_base: PyModuleDef_HEAD_INIT,
|
|
||||||
m_name: std::ptr::null(),
|
|
||||||
m_doc: std::ptr::null(),
|
|
||||||
m_size: 0,
|
|
||||||
m_methods: std::ptr::null_mut(),
|
|
||||||
m_slots: std::ptr::null_mut(),
|
|
||||||
m_traverse: None,
|
|
||||||
m_clear: None,
|
|
||||||
m_free: None,
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue