pyo3/tests/test_macros.rs

94 lines
2.4 KiB
Rust
Raw Normal View History

2021-12-03 00:03:32 +00:00
#![cfg(feature = "macros")]
2020-04-04 08:38:04 +00:00
//! Ensure that pyo3 macros can be used inside macro_rules!
use pyo3::prelude::*;
2020-04-04 08:38:04 +00:00
#[macro_use]
2023-09-24 12:34:53 +00:00
#[path = "../src/tests/common.rs"]
2020-04-04 08:38:04 +00:00
mod common;
macro_rules! make_struct_using_macro {
// Ensure that one doesn't need to fall back on the escape type: tt
// in order to macro create pyclass.
2020-04-04 08:38:04 +00:00
($class_name:ident, $py_name:literal) => {
#[pyclass(name=$py_name)]
struct $class_name {}
};
}
make_struct_using_macro!(MyBaseClass, "MyClass");
macro_rules! set_extends_via_macro {
($class_name:ident, $base_class:path) => {
// Try and pass a variable into the extends parameter
#[pyclass(extends=$base_class)]
struct $class_name {}
};
}
set_extends_via_macro!(MyClass2, MyBaseClass);
//
// Check that pyfunctiona nd text_signature can be called with macro arguments.
//
macro_rules! fn_macro {
($sig:literal, $a_exp:expr, $b_exp:expr, $c_exp: expr) => {
// Try and pass a variable into the signature parameter
#[pyfunction(signature = ($a_exp, $b_exp, *, $c_exp))]
2020-04-04 08:38:04 +00:00
#[pyo3(text_signature = $sig)]
fn my_function_in_macro(a: i32, b: Option<i32>, c: i32) {
let _ = (a, b, c);
}
};
}
fn_macro!("(a, b=None, *, c=42)", a, b = None, c = 42);
2020-04-04 08:38:04 +00:00
2020-04-13 06:12:04 +00:00
macro_rules! property_rename_via_macro {
($prop_name:ident) => {
#[pyclass]
struct ClassWithProperty {
member: u64,
}
#[pymethods]
impl ClassWithProperty {
#[getter($prop_name)]
fn get_member(&self) -> u64 {
self.member
}
#[setter($prop_name)]
fn set_member(&mut self, member: u64) {
self.member = member;
}
}
};
}
property_rename_via_macro!(my_new_property_name);
2020-04-04 08:38:04 +00:00
#[test]
fn test_macro_rules_interactions() {
Python::with_gil(|py| {
let my_base = py.get_type_bound::<MyBaseClass>();
2020-04-04 08:38:04 +00:00
py_assert!(py, my_base, "my_base.__name__ == 'MyClass'");
let my_func = wrap_pyfunction_bound!(my_function_in_macro, py).unwrap();
2020-04-04 08:38:04 +00:00
py_assert!(
py,
my_func,
"my_func.__text_signature__ == '(a, b=None, *, c=42)'"
);
2020-04-13 06:12:04 +00:00
let renamed_prop = py.get_type_bound::<ClassWithProperty>();
2020-04-13 06:12:04 +00:00
py_assert!(
py,
renamed_prop,
"hasattr(renamed_prop, 'my_new_property_name')"
);
2020-04-04 08:38:04 +00:00
});
}