diff --git a/pyo3cls/src/module.rs b/pyo3cls/src/module.rs index 25f4cd8b..332ec552 100644 --- a/pyo3cls/src/module.rs +++ b/pyo3cls/src/module.rs @@ -38,6 +38,7 @@ pub fn build_py3_module_init(ast: &mut syn::Item, attr: String) -> Tokens { } pub fn py3_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens { + let m_name = syn::Ident::from(name.trim().as_ref()); let cb_name = syn::Ident::from(format!("PyInit_{}", name.trim()).as_ref()); quote! { #[no_mangle] @@ -47,13 +48,13 @@ pub fn py3_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens { use std; use pyo3::{IntoPyPointer, ObjectProtocol}; - // initialize python - pyo3::prepare_freethreaded_python(); + // initialize pyo3 + pyo3::prepare_pyo3_library(); static mut MODULE_DEF: pyo3::ffi::PyModuleDef = pyo3::ffi::PyModuleDef_INIT; // We can't convert &'static str to *const c_char within a static initializer, // so we'll do it here in the module initialization: - MODULE_DEF.m_name = concat!(stringify!(#cb_name), "\0").as_ptr() as *const _; + MODULE_DEF.m_name = concat!(stringify!(#m_name), "\0").as_ptr() as *const _; pyo3::callback::cb_meth("py_module_init", |py| { pyo3::ffi::PyEval_InitThreads(); @@ -112,6 +113,7 @@ pub fn build_py2_module_init(ast: &mut syn::Item, attr: String) -> Tokens { } pub fn py2_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens { + let m_name = syn::Ident::from(name.trim().as_ref()); let cb_name = syn::Ident::from(format!("init{}", name.trim()).as_ref()); quote! { @@ -122,12 +124,12 @@ pub fn py2_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens { use std; // initialize python - pyo3::prepare_freethreaded_python(); + pyo3::prepare_pyo3_library(); + ffi::PyEval_InitThreads(); - let name = concat!(stringify!(#cb_name), "\0").as_ptr() as *const _; + let name = concat!(stringify!(#m_name), "\0").as_ptr() as *const _; let guard = pyo3::callback::AbortOnDrop("py_module_initializer"); let py = pyo3::Python::assume_gil_acquired(); - pyo3::ffi::PyEval_InitThreads(); let module = pyo3::ffi::Py_InitModule(name, std::ptr::null_mut()); if module.is_null() { std::mem::forget(guard); @@ -143,12 +145,10 @@ pub fn py2_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens { } }; module.add("__doc__", #doc).expect("Failed to add doc for module"); - let ret = match #fnname(py, module) { - Ok(()) => (), - Err(e) => e.restore(py) - }; + if let Err(e) = #fnname(py, module) { + e.restore(py) + } std::mem::forget(guard); - ret } } } diff --git a/src/lib.rs b/src/lib.rs index 75d55f01..4840e26c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,7 +158,7 @@ pub use objectprotocol::ObjectProtocol; pub use pointer::PyObject; pub use python::{Python, ToPyPointer, IntoPyPointer, PyClone, PyMutDowncastFrom, PyDowncastFrom, PyDowncastInto}; -pub use pythonrun::{GILGuard, prepare_freethreaded_python}; +pub use pythonrun::{GILGuard, prepare_freethreaded_python, prepare_pyo3_library}; pub use instance::{PyToken, PyObjectWithToken, AsPyRef, Py, PyNativeType}; pub use conversion::{FromPyObject, ToPyObject, IntoPyObject, IntoPyTuple}; pub mod class; diff --git a/src/pythonrun.rs b/src/pythonrun.rs index c0569e46..3dd83ea6 100644 --- a/src/pythonrun.rs +++ b/src/pythonrun.rs @@ -9,6 +9,7 @@ use pointer::PyObject; use objects::PyInstance; static START: sync::Once = sync::ONCE_INIT; +static START_PYO3: sync::Once = sync::ONCE_INIT; /// Prepares the use of Python in a free-threaded context. /// @@ -60,6 +61,13 @@ pub fn prepare_freethreaded_python() { // and will be restored by PyGILState_Ensure. } + prepare_pyo3_library(); + }); +} + +#[doc(hidden)] +pub fn prepare_pyo3_library() { + START_PYO3.call_once(|| unsafe { // initialize release pool POOL = Box::into_raw(Box::new(Vec::with_capacity(250))); });