From bda5c6c9df8e1955428d7f332aa85b2e9f3102f2 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 24 Jul 2025 14:57:48 +0200 Subject: [PATCH] Simplify packer module init Using `OnceLockExt` instead of `GILOnceCell` for simpler code and fewer caveats. See also: https://pyo3.rs/v0.25.1/free-threading.html?highlight=free#thread-safe-single-initialization --- src/codec/packstream/v1/pack.rs | 36 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/codec/packstream/v1/pack.rs b/src/codec/packstream/v1/pack.rs index 5f89b6a..dfa64ca 100644 --- a/src/codec/packstream/v1/pack.rs +++ b/src/codec/packstream/v1/pack.rs @@ -14,11 +14,11 @@ // limitations under the License. use std::borrow::Cow; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::OnceLock; -use pyo3::exceptions::{PyImportError, PyOverflowError, PyTypeError, PyValueError}; +use pyo3::exceptions::{PyOverflowError, PyTypeError, PyValueError}; use pyo3::prelude::*; -use pyo3::sync::GILOnceCell; +use pyo3::sync::OnceLockExt; use pyo3::types::{PyBytes, PyDict, PyString, PyType}; use pyo3::{intern, IntoPyObjectExt}; @@ -97,29 +97,19 @@ impl TypeMappings { } } -static TYPE_MAPPINGS: GILOnceCell> = GILOnceCell::new(); -static TYPE_MAPPINGS_INIT: AtomicBool = AtomicBool::new(false); +static TYPE_MAPPINGS: OnceLock> = OnceLock::new(); fn get_type_mappings(py: Python<'_>) -> PyResult<&'static TypeMappings> { - let mappings = TYPE_MAPPINGS.get_or_try_init(py, || { - fn init(py: Python<'_>) -> PyResult { - let locals = PyDict::new(py); - py.run( - c"from neo4j._codec.packstream.v1.types import *", - None, - Some(&locals), - )?; - TypeMappings::new(&locals) - } - - if TYPE_MAPPINGS_INIT.swap(true, Ordering::SeqCst) { - return Err(PyErr::new::( - "Cannot call _rust.pack while loading `neo4j._codec.packstream.v1.types`", - )); - } - Ok(init(py)) + let mappings = TYPE_MAPPINGS.get_or_init_py_attached(py, || { + let locals = PyDict::new(py); + py.run( + c"from neo4j._codec.packstream.v1.types import *", + None, + Some(&locals), + )?; + TypeMappings::new(&locals) }); - mappings?.as_ref().map_err(|e| e.clone_ref(py)) + mappings.as_ref().map_err(|e| e.clone_ref(py)) } #[pyfunction]