Skip to content

Commit 311b938

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 a2c6266 commit 311b938

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

src/impl_/pymodule.rs

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

2626
#[cfg(not(any(PyPy, GraalPy)))]
2727
use crate::exceptions::PyImportError;
28+
use crate::exceptions::PyRuntimeError;
29+
use crate::impl_::trampoline::trampoline;
2830
use crate::prelude::PyTypeMethods;
2931
use crate::{
3032
ffi,
@@ -319,20 +321,20 @@ impl PyAddToModule for ModuleDef {
319321
/// [`Py_mod_exec`]: https://docs.python.org/3/c-api/module.html#c.Py_mod_exec
320322
pub unsafe extern "C" fn pyo3_module_state_init(module: *mut ffi::PyObject) -> c_int {
321323
unsafe {
322-
let state: *mut MaybeUninit<ModuleState> = ffi::PyModule_GetState(module).cast();
324+
trampoline(|_| {
325+
let state: *mut MaybeUninit<ModuleState> = ffi::PyModule_GetState(module).cast();
323326

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-
}
327+
// CPython builtins just assert this, but cross ffi panics are tricky, so we return an
328+
// error instead
329+
if state.is_null() {
330+
return Err(PyRuntimeError::new_err("PyO3 per-module state was null. This is a bug in the Python interpreter runtime."));
331+
}
331332

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

335-
0
335+
Ok(0)
336+
})
337+
}
336338
}
337339

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

0 commit comments

Comments
 (0)