From 775e917a657034704af0f55836b91afdc49f720e Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Sat, 22 Oct 2022 12:30:22 +0100 Subject: [PATCH] document and test raw idents with signature --- guide/src/function/signature.md | 12 ++++++++++++ pyo3-macros-backend/src/pyfunction/signature.rs | 4 ++-- tests/test_methods.rs | 9 +++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/guide/src/function/signature.md b/guide/src/function/signature.md index 4ead0b40d54..2b9741c2cfe 100644 --- a/guide/src/function/signature.md +++ b/guide/src/function/signature.md @@ -94,6 +94,18 @@ num=44 num=-1 ``` +> Note: for keywords like `struct`, to use it as a function argument, use "raw ident" syntax `r#struct` in both the signature and the function definition: +> +> ```rust +> # !#[allow(unused_code)] +> # use pyo3::prelude::*; +> #[pyfunction(signature = (r#struct = "foo"))] +> fn method_with_keyword<'a>(&self, r#struct: &'a str) { +> # let _ = r#struct; +> /* ... */ +> } +> ``` + ## Deprecated form The `#[pyfunction]` macro can take the argument specification directly, but this method is deprecated in PyO3 0.18 because the `#[pyo3(signature)]` option offers a simpler syntax and better validation. diff --git a/pyo3-macros-backend/src/pyfunction/signature.rs b/pyo3-macros-backend/src/pyfunction/signature.rs index e08ba03edf7..e66f14bc53f 100644 --- a/pyo3-macros-backend/src/pyfunction/signature.rs +++ b/pyo3-macros-backend/src/pyfunction/signature.rs @@ -348,11 +348,11 @@ impl<'a> FunctionSignature<'a> { let mut next_argument_checked = |name: &syn::Ident| match args_iter.next() { Some(fn_arg) => { ensure_spanned!( - name == &fn_arg.name.unraw(), + name == fn_arg.name, name.span() => format!( "expected argument from function definition `{}` but got argument `{}`", fn_arg.name.unraw(), - name, + name.unraw(), ) ); Ok(fn_arg) diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 379149f9e96..9dddbd351be 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -1344,6 +1344,11 @@ impl r#RawIdents { #[classattr] const r#CLASS_ATTR_CONST: i32 = 6; + + #[pyo3(signature = (r#struct = "foo"))] + fn method_with_keyword<'a>(&self, r#struct: &'a str) -> &'a str { + r#struct + } } #[test] @@ -1377,6 +1382,10 @@ fn test_raw_idents() { assert raw_idents_type.class_attr_fn == 5 assert raw_idents_type.CLASS_ATTR_CONST == 6 + + assert instance.method_with_keyword() == "foo" + assert instance.method_with_keyword("bar") == "bar" + assert instance.method_with_keyword(struct="baz") == "baz" "# ); })