Add intern macro to hygiene tests and ensure it can handle stringified identifiers.

This commit is contained in:
Adam Reichold 2022-04-04 18:44:19 +02:00
parent f777372eed
commit 30d414fd49
2 changed files with 34 additions and 2 deletions

View File

@ -141,12 +141,38 @@ impl<T> GILOnceCell<T> {
/// ```
#[macro_export]
macro_rules! intern {
($py: expr, $text: literal) => {{
($py: expr, $text: expr) => {{
static INTERNED: $crate::once_cell::GILOnceCell<$crate::Py<$crate::types::PyString>> =
$crate::once_cell::GILOnceCell::new();
INTERNED
.get_or_init($py, || $crate::types::PyString::intern($py, $text).into())
.get_or_init($py, || {
$crate::conversion::IntoPy::into_py(
$crate::types::PyString::intern($py, $text),
$py,
)
})
.as_ref($py)
}};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::PyDict;
#[test]
fn test_intern() {
Python::with_gil(|py| {
let foo1 = "foo";
let foo2 = intern!(py, "foo");
let foo3 = intern!(py, stringify!(foo));
let dict = PyDict::new(py);
dict.set_item(foo1, 42_usize).unwrap();
assert!(dict.contains(foo2).unwrap());
assert_eq!(dict.get_item(foo3).unwrap().extract::<usize>().unwrap(), 42);
});
}
}

View File

@ -27,3 +27,9 @@ enum Derive4 {
crate::create_exception!(mymodule, CustomError, crate::exceptions::PyException);
crate::import_exception!(socket, gaierror);
#[allow(dead_code)]
fn intern(py: crate::Python<'_>) {
let _foo = crate::intern!(py, "foo");
let _bar = crate::intern!(py, stringify!(bar));
}