-
Notifications
You must be signed in to change notification settings - Fork 697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't use rust keywords as python function names #4225
Comments
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/latest/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust > keyword, though parsing one through its > [`Parse`](https://docs.rs/syn/latest/syn/parse/trait.Parse.html) > implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` > when parsing to match the behaviour of `Ident::new`. Fixes issue PyO3#4225
Created #4226 to fix this issue. |
This is also already possibly by using a raw identifier: #[pyo3(name = "r#struct")]
fn struct_method(&self) -> usize {
42
} |
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/2.0.66/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust keyword, though parsing one through its [`Parse`](https://docs.rs/syn/2.0.66/syn/parse/trait.Parse.html) implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the behaviour of `Ident::new`. Fixes issue PyO3#4225
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/2.0.66/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust keyword, though parsing one through its [`Parse`](https://docs.rs/syn/2.0.66/syn/parse/trait.Parse.html) implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the behaviour of `Ident::new`. Fixes issue PyO3#4225
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/2.0.66/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust keyword, though parsing one through its [`Parse`](https://docs.rs/syn/2.0.66/syn/parse/trait.Parse.html) implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the behaviour of `Ident::new`. Fixes issue PyO3#4225
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/2.0.66/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust keyword, though parsing one through its [`Parse`](https://docs.rs/syn/2.0.66/syn/parse/trait.Parse.html) implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the behaviour of `Ident::new`. Fixes issue PyO3#4225
This does work for the method, thanks: >>> import pyo3_example
>>> m = pyo3_example.MyClass()
>>> m.struct()
42 But it does not work for the standalone function: >>> import pyo3_example
>>> pyo3_example.struct()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'pyo3_example' has no attribute 'struct'. Did you mean: 'r#struct'?
>>> pyo3_example.r#struct
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'pyo3_example' has no attribute 'r'
>>> pyo3_example["r#struct"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not subscriptable
error: expected string literal
--> src/lib.rs:21:15
|
21 | #[pyo3(name = r#struct)]
| ^^^^^^^^ |
It does work for standalone functions, if you use the raw identifier for the function itself: #[pyfunction]
fn r#struct() -> usize {
42
} The syntax for the #[pyfunction]
#[pyo3(name = "r#struct")]
fn some_function -> usize {
42
} But this currently does also not work, but I would consider that a bug (I did track that down already, so fixing that should be easy). |
I'd hope that #[pyfunction]
#[pyo3(name = "r#struct")]
fn some_function -> usize {
42
} to continue to be invalid. |
Just for reference, your example is not invalid (in the sense that is does compile just fine), it just produces no usable function on the Python side. |
😬 |
This makes it possible to use rust keywords as the name of python class methods and standalone functions. For example: ``` struct MyClass { } impl MyClass { #[new] fn new() -> Self { MyClass {} } #[pyo3(name = "struct")] fn struct_method(&self) -> usize { 42 } } fn struct_function() -> usize { 42 } ``` From the [`syn::Ident` documentation](https://docs.rs/syn/2.0.66/syn/struct.Ident.html): > An identifier constructed with `Ident::new` is permitted to be a Rust keyword, though parsing one through its [`Parse`](https://docs.rs/syn/2.0.66/syn/parse/trait.Parse.html) implementation rejects Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the behaviour of `Ident::new`. Fixes issue #4225
Bug Description
Using a rust keyword as the name of a function, e.g.
#[pyo3(name = "<struct>")]
results in a compilation error.Steps to Reproduce
Sample program:
Backtrace
Your operating system and version
Your Python version (
python --version
)Python 3.12.3
Your Rust version (
rustc --version
)rustc 1.80.0-nightly (867900499 2024-05-23)
Your PyO3 version
0.21.2
How did you install python? Did you use a virtualenv?
Additional Info
struct
is not a reserved word in Python, so it works normally as Python code:The text was updated successfully, but these errors were encountered: