Skip to content

Commit

Permalink
Merge pull request #1630 from davidhewitt/module-init
Browse files Browse the repository at this point in the history
pymodule: tidy up module init
  • Loading branch information
messense authored May 26, 2021
2 parents b3946c3 + 3e87ea3 commit 0acc8bd
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 45 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Deprecate `#[name = "..."]` attributes in favor of `#[pyo3(name = "...")]`. [#1567](/~https://github.com/PyO3/pyo3/pull/1567)
- Reduce LLVM line counts to improve compilation times. [#1604](/~https://github.com/PyO3/pyo3/pull/1604)
- Deprecate string-literal second argument to `#[pyfn(m, "name")]`. [#1610](/~https://github.com/PyO3/pyo3/pull/1610)
- No longer call `PyEval_InitThreads()` in `#[pymodule]` init code. [#1630](/~https://github.com/PyO3/pyo3/pull/1630)

### Removed
- Remove deprecated exception names `BaseException` etc. [#1426](/~https://github.com/PyO3/pyo3/pull/1426)
Expand All @@ -57,6 +58,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Remove pyclass implementation details from `PyTypeInfo`:
- `Type`, `DESCRIPTION`, and `FLAGS` [#1456](/~https://github.com/PyO3/pyo3/pull/1456)
- `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 `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. [#1521](/~https://github.com/PyO3/pyo3/pull/1521)

Expand Down
7 changes: 4 additions & 3 deletions pyo3-macros-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ pub fn py_init(fnname: &Ident, name: &Ident, doc: syn::LitStr) -> TokenStream {
/// the module.
pub unsafe extern "C" fn #cb_name() -> *mut pyo3::ffi::PyObject {
use pyo3::derive_utils::ModuleDef;
const NAME: &'static str = concat!(stringify!(#name), "\0");
static MODULE_DEF: ModuleDef = unsafe { ModuleDef::new(NAME) };
static NAME: &str = concat!(stringify!(#name), "\0");
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) })
}
}
}
Expand Down
49 changes: 23 additions & 26 deletions src/derive_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::exceptions::PyTypeError;
use crate::instance::PyNativeType;
use crate::pyclass::PyClass;
use crate::types::{PyAny, PyDict, PyModule, PyString, PyTuple};
use crate::{ffi, GILPool, PyCell, Python};
use crate::{ffi, PyCell, Python};
use std::cell::UnsafeCell;

#[derive(Debug)]
Expand Down Expand Up @@ -281,7 +281,6 @@ pub fn argument_extraction_error(py: Python, arg_name: &str, error: PyErr) -> Py
}

/// `Sync` wrapper of `ffi::PyModuleDef`.
#[doc(hidden)]
pub struct ModuleDef(UnsafeCell<ffi::PyModuleDef>);

unsafe impl Sync for ModuleDef {}
Expand All @@ -291,35 +290,33 @@ impl ModuleDef {
///
/// # Safety
/// `name` must be a null-terminated string.
pub const unsafe fn new(name: &'static str) -> Self {
#[allow(deprecated)]
let mut init = ffi::PyModuleDef_INIT;
init.m_name = name.as_ptr() as *const _;
ModuleDef(UnsafeCell::new(init))
pub const unsafe fn new(name: &'static str, doc: &'static str) -> Self {
const INIT: ffi::PyModuleDef = ffi::PyModuleDef {
m_base: ffi::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,
};

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]`.
///
/// # Safety
/// The caller must have GIL.
pub unsafe fn make_module(
pub fn make_module(
&'static self,
doc: &str,
py: Python,
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
) -> PyResult<*mut ffi::PyObject> {
#[cfg(py_sys_config = "WITH_THREAD")]
// > Changed in version 3.7: This function is now called by Py_Initialize(), so you don’t have
// > to call it yourself anymore.
#[cfg(not(Py_3_7))]
ffi::PyEval_InitThreads();

let module = ffi::PyModule_Create(self.0.get());
let pool = GILPool::new();
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)?;
let module =
unsafe { py.from_owned_ptr_or_err::<PyModule>(ffi::PyModule_Create(self.0.get()))? };
initializer(py, module)?;
Ok(crate::IntoPyPointer::into_ptr(module))
}
Expand Down
16 changes: 0 additions & 16 deletions src/ffi/moduleobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,3 @@ pub struct PyModuleDef {
pub m_clear: Option<inquiry>,
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,
};

0 comments on commit 0acc8bd

Please sign in to comment.