Skip to content

Commit d5979a8

Browse files
Fall back to intern if not valid CStr
1 parent 3a03dee commit d5979a8

1 file changed

Lines changed: 20 additions & 34 deletions

File tree

src/sync.rs

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,7 @@
99
//! interpreter.
1010
//!
1111
//! This module provides synchronization primitives which are able to synchronize under these conditions.
12-
use crate::{
13-
internal::state::SuspendAttach,
14-
sealed::Sealed,
15-
types::{PyAny, PyString},
16-
Borrowed, Bound, Py, Python,
17-
};
18-
use std::ffi::CStr;
12+
use crate::{internal::state::SuspendAttach, sealed::Sealed, types::PyAny, Bound, Python};
1913
use std::{
2014
cell::UnsafeCell,
2115
marker::PhantomData,
@@ -230,38 +224,27 @@ impl<T> Drop for GILOnceCell<T> {
230224
#[macro_export]
231225
macro_rules! intern {
232226
($py: expr, $text: expr) => {{
233-
const _CSTR: &::std::ffi::CStr = {
227+
const STRING: ::std::result::Result<&::std::ffi::CStr, &str> = {
234228
match ::std::ffi::CStr::from_bytes_with_nul(concat!($text, "\0").as_bytes()) {
235-
::std::result::Result::Ok(s) => s,
236-
::std::result::Result::Err(_) => {
237-
::std::panic!("interned string cannot contain interior null bytes")
238-
}
229+
::std::result::Result::Ok(c_str) => ::std::result::Result::Ok(c_str),
230+
::std::result::Result::Err(_) => ::std::result::Result::Err($text),
239231
}
240232
};
241-
static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new(_CSTR);
242-
INTERNED.get($py)
233+
static INTERNED: $crate::sync::PyOnceLock<$crate::Py<$crate::types::PyString>> =
234+
$crate::sync::PyOnceLock::new();
235+
INTERNED
236+
.get_or_init($py, || match STRING {
237+
::std::result::Result::Ok(c_str) => {
238+
$crate::types::PyString::intern_cstr($py, c_str).unbind()
239+
}
240+
::std::result::Result::Err(string) => {
241+
$crate::types::PyString::intern($py, string).unbind()
242+
}
243+
})
244+
.bind_borrowed($py)
243245
}};
244246
}
245247

246-
/// Implementation detail for `intern!` macro.
247-
#[doc(hidden)]
248-
pub struct Interned(&'static CStr, PyOnceLock<Py<PyString>>);
249-
250-
impl Interned {
251-
/// Creates an empty holder for an interned `str`.
252-
pub const fn new(value: &'static CStr) -> Self {
253-
Interned(value, PyOnceLock::new())
254-
}
255-
256-
/// Gets or creates the interned `str` value.
257-
#[inline]
258-
pub fn get<'py>(&self, py: Python<'py>) -> Borrowed<'_, 'py, PyString> {
259-
self.1
260-
.get_or_init(py, || PyString::intern_cstr(py, self.0).unbind())
261-
.bind_borrowed(py)
262-
}
263-
}
264-
265248
/// Extension trait for [`Once`] to help avoid deadlocking when using a [`Once`] when attached to a
266249
/// Python thread.
267250
pub trait OnceExt: Sealed {
@@ -735,7 +718,10 @@ mod rwlock_ext_sealed {
735718
mod tests {
736719
use super::*;
737720

738-
use crate::types::{PyAnyMethods, PyDict, PyDictMethods};
721+
use crate::{
722+
types::{PyAnyMethods, PyDict, PyDictMethods},
723+
Py,
724+
};
739725
#[cfg(not(target_arch = "wasm32"))]
740726
#[cfg(feature = "macros")]
741727
use std::sync::atomic::{AtomicBool, Ordering};

0 commit comments

Comments
 (0)