macros: simpler expansion for intern!
This commit is contained in:
parent
2769963536
commit
261c0c5f56
|
@ -1,5 +1,5 @@
|
|||
//! A write-once cell mediated by the Python GIL.
|
||||
use crate::Python;
|
||||
use crate::{types::PyString, Py, Python};
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
/// A write-once cell similar to [`once_cell::OnceCell`](https://docs.rs/once_cell/1.4.0/once_cell/).
|
||||
|
@ -151,24 +151,28 @@ impl<T> GILOnceCell<T> {
|
|||
#[macro_export]
|
||||
macro_rules! intern {
|
||||
($py: expr, $text: expr) => {{
|
||||
fn isolate_from_dyn_env(py: $crate::Python<'_>) -> &$crate::types::PyString {
|
||||
static INTERNED: $crate::once_cell::GILOnceCell<$crate::Py<$crate::types::PyString>> =
|
||||
$crate::once_cell::GILOnceCell::new();
|
||||
|
||||
INTERNED
|
||||
.get_or_init(py, || {
|
||||
$crate::conversion::IntoPy::into_py(
|
||||
$crate::types::PyString::intern(py, $text),
|
||||
py,
|
||||
)
|
||||
})
|
||||
.as_ref(py)
|
||||
}
|
||||
|
||||
isolate_from_dyn_env($py)
|
||||
static INTERNED: $crate::once_cell::Interned = $crate::once_cell::Interned::new($text);
|
||||
INTERNED.get($py)
|
||||
}};
|
||||
}
|
||||
|
||||
/// Implementation detail for `intern!` macro.
|
||||
#[doc(hidden)]
|
||||
pub struct Interned(&'static str, GILOnceCell<Py<PyString>>);
|
||||
|
||||
impl Interned {
|
||||
pub const fn new(value: &'static str) -> Self {
|
||||
Interned(value, GILOnceCell::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get<'py>(&'py self, py: Python<'py>) -> &'py PyString {
|
||||
self.1
|
||||
.get_or_init(py, || PyString::intern(py, self.0).into())
|
||||
.as_ref(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -94,6 +94,7 @@ fn _test_compile_errors() {
|
|||
|
||||
#[rustversion::since(1.60)]
|
||||
fn tests_rust_1_60(t: &trybuild::TestCases) {
|
||||
t.compile_fail("tests/ui/invalid_intern_arg.rs");
|
||||
t.compile_fail("tests/ui/invalid_immutable_pyclass_borrow.rs");
|
||||
t.compile_fail("tests/ui/invalid_pymethod_receiver.rs");
|
||||
t.compile_fail("tests/ui/missing_intopy.rs");
|
||||
|
|
6
tests/ui/invalid_intern_arg.rs
Normal file
6
tests/ui/invalid_intern_arg.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use pyo3::Python;
|
||||
|
||||
fn main() {
|
||||
let foo = if true { "foo" } else { "bar" };
|
||||
Python::with_gil(|py| py.import(pyo3::intern!(py, foo)).unwrap());
|
||||
}
|
8
tests/ui/invalid_intern_arg.stderr
Normal file
8
tests/ui/invalid_intern_arg.stderr
Normal file
|
@ -0,0 +1,8 @@
|
|||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> tests/ui/invalid_intern_arg.rs:5:55
|
||||
|
|
||||
5 | Python::with_gil(|py| py.import(pyo3::intern!(py, foo)).unwrap());
|
||||
| ------------------^^^-
|
||||
| | |
|
||||
| | non-constant value
|
||||
| help: consider using `let` instead of `static`: `let INTERNED`
|
Loading…
Reference in a new issue