Skip to content

Commit 9ccfc08

Browse files
committed
src/impl_: use trampoline in pyo3_module_state_init
So we can return a real error if our state ptr is null. The upstream cpython builtins just assert non-null, so this is probably fine References: https://github.com/python/cpython/blob/v3.13.0/Modules/_sqlite/module.h#L80-L81 References: https://github.com/python/cpython/blob/v3.13.0/Modules/_io/_iomodule.h#L172-L173 References: https://github.com/python/cpython/blob/v3.13.0/Modules/_blake2/blake2module.c#L33-L34
1 parent 8936c8a commit 9ccfc08

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/impl_/pymodule.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::sync::atomic::{AtomicI64, Ordering};
2525

2626
#[cfg(not(any(PyPy, GraalPy)))]
2727
use crate::exceptions::PyImportError;
28+
use crate::impl_::trampoline::trampoline;
2829
use crate::prelude::PyTypeMethods;
2930
use crate::{
3031
ffi,
@@ -319,20 +320,20 @@ impl PyAddToModule for ModuleDef {
319320
/// [`Py_mod_exec`]: https://docs.python.org/3/c-api/module.html#c.Py_mod_exec
320321
pub unsafe extern "C" fn pyo3_module_state_init(module: *mut ffi::PyObject) -> c_int {
321322
unsafe {
322-
let state: *mut MaybeUninit<ModuleState> = ffi::PyModule_GetState(module).cast();
323+
trampoline(|_| {
324+
let state: *mut MaybeUninit<ModuleState> = ffi::PyModule_GetState(module).cast();
323325

324-
if state.is_null() {
325-
// TODO: Not sure what to do here... but it means m_size was <= 0
326-
// so we have no memory space to write into...
327-
//
328-
// Set a PyErr and return -1?
329-
return 0;
330-
}
326+
// CPython builtins just assert this, but cross ffi panics are tricky, so we return an
327+
// error instead
328+
if state.is_null() {
329+
return Err(PyImportError::new_err("PyO3 per-module state was null. This is a bug in the Python interpreter runtime."));
330+
}
331331

332-
(*state).write(ModuleState::new());
333-
}
332+
(*state).write(ModuleState::new());
334333

335-
0
334+
Ok(0)
335+
})
336+
}
336337
}
337338

338339
/// Called during deallocation of the module object.

0 commit comments

Comments
 (0)