diff --git a/CHANGELOG.md b/CHANGELOG.md index 705e859f473..260e68fab8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `indexmap` feature to add `ToPyObject`, `IntoPy` and `FromPyObject` implementations for `indexmap::IndexMap`. [#1728](https://github.com/PyO3/pyo3/pull/1728) - Add `pyo3_build_config::add_extension_module_link_args()` to use in build scripts to set linker arguments (for macOS). [#1755](https://github.com/PyO3/pyo3/pull/1755) +- Add `Python::acquire_gil_no_checks()` unsafe variation of `Python::acquire_gil()` to allow the GIL to be obtained without performing interpreter initialization checks. ### Changed diff --git a/src/gil.rs b/src/gil.rs index 8d1832e7ad7..2c2e6a079df 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -241,6 +241,15 @@ impl GILGuard { } } + Self::acquire_no_checks() + } + + /// Acquires the `GILGuard` without performing any state checking. + /// + /// This can be called in "unsafe" contexts where the normal interpreter state + /// checking performed by `GILGuard::acquire` may fail. This includes calling + /// as part of multi-phase interpreter initialization. + pub(crate) fn acquire_no_checks() -> GILGuard { let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL // If there's already a GILPool, we should not create another or this could lead to diff --git a/src/python.rs b/src/python.rs index 03fd9995773..49e0314b0c2 100644 --- a/src/python.rs +++ b/src/python.rs @@ -189,6 +189,24 @@ impl<'p> Python<'p> { GILGuard::acquire() } + /// Acquires the [GILGuard] without performing state checking. + /// + /// # Safety + /// + /// This bypasses checking that [Python::acquire] would normally perform, such + /// as ensuring the Python interpreter is fully initialized. If you call this + /// from a process where the Python interpreter isn't in a "good" state, the + /// process may crash. + /// + /// One special case where calling this function over [Python::acquire_gil] is + /// justified is during multi-phase interpreter initialization. If the interpreter + /// is configured for multi-phase initialization, it is safe to call this function + /// between `Py_InitializeFromConfig()` and `_Py_InitializeMain()`. + #[inline] + pub unsafe fn acquire_gil_no_checks() -> GILGuard { + GILGuard::acquire_no_checks() + } + /// Temporarily releases the `GIL`, thus allowing other Python threads to run. /// /// # Examples