Allow #[name] with #[getter] and #[setter]

This commit is contained in:
scalexm 2021-03-18 19:35:17 +01:00
parent 20452a7c09
commit b27ee3fd64
3 changed files with 24 additions and 5 deletions

View file

@ -468,7 +468,16 @@ fn parse_method_attributes(
*attrs = new_attrs; *attrs = new_attrs;
let python_name = if allow_custom_name { let python_name = if allow_custom_name {
parse_method_name_attribute(ty.as_ref(), attrs, property_name)? match parse_method_name_attribute(ty.as_ref(), attrs)? {
Some(python_name) if property_name.is_some() => {
return Err(syn::Error::new_spanned(
python_name,
"name cannot be specified twice",
));
}
Some(python_name) => Some(python_name),
None => property_name,
}
} else { } else {
property_name property_name
}; };
@ -483,14 +492,13 @@ fn parse_method_attributes(
fn parse_method_name_attribute( fn parse_method_name_attribute(
ty: Option<&MethodTypeAttribute>, ty: Option<&MethodTypeAttribute>,
attrs: &mut Vec<syn::Attribute>, attrs: &mut Vec<syn::Attribute>,
property_name: Option<syn::Ident>,
) -> syn::Result<Option<syn::Ident>> { ) -> syn::Result<Option<syn::Ident>> {
use MethodTypeAttribute::*; use MethodTypeAttribute::*;
let name = parse_name_attribute(attrs)?; let name = parse_name_attribute(attrs)?;
// Reject some invalid combinations // Reject some invalid combinations
if let (Some(name), Some(ty)) = (&name, ty) { if let (Some(name), Some(ty)) = (&name, ty) {
if let New | Call | Getter | Setter = ty { if let New | Call = ty {
bail_spanned!(name.span() => "name not allowed with this method type"); bail_spanned!(name.span() => "name not allowed with this method type");
} }
} }
@ -499,7 +507,6 @@ fn parse_method_name_attribute(
Ok(match ty { Ok(match ty {
Some(New) => Some(syn::Ident::new("__new__", proc_macro2::Span::call_site())), Some(New) => Some(syn::Ident::new("__new__", proc_macro2::Span::call_site())),
Some(Call) => Some(syn::Ident::new("__call__", proc_macro2::Span::call_site())), Some(Call) => Some(syn::Ident::new("__call__", proc_macro2::Span::call_site())),
Some(Getter) | Some(Setter) => property_name,
_ => name, _ => name,
}) })
} }

View file

@ -78,6 +78,12 @@ impl EmptyClass2 {
#[staticmethod] #[staticmethod]
#[name = "custom_static"] #[name = "custom_static"]
fn bar_static() {} fn bar_static() {}
#[getter]
#[name = "custom_getter"]
fn foo(&self) -> i32 {
5
}
} }
#[test] #[test]
@ -92,8 +98,14 @@ fn custom_names() {
typeobj, typeobj,
"typeobj.custom_static.__name__ == 'custom_static'" "typeobj.custom_static.__name__ == 'custom_static'"
); );
py_assert!(
py,
typeobj,
"typeobj.custom_getter.__name__ == 'custom_getter'"
);
py_assert!(py, typeobj, "not hasattr(typeobj, 'bar')"); py_assert!(py, typeobj, "not hasattr(typeobj, 'bar')");
py_assert!(py, typeobj, "not hasattr(typeobj, 'bar_static')"); py_assert!(py, typeobj, "not hasattr(typeobj, 'bar_static')");
py_assert!(py, typeobj, "not hasattr(typeobj, 'foo')");
} }
#[pyclass] #[pyclass]

View file

@ -1,4 +1,4 @@
error: name not allowed with this method type error: name cannot be specified twice
--> $DIR/invalid_pymethod_names.rs:10:5 --> $DIR/invalid_pymethod_names.rs:10:5
| |
10 | #[name = "num"] 10 | #[name = "num"]