Skip to content

Commit

Permalink
fix empty and single element tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
newcomertv committed May 10, 2024
1 parent f39cb0a commit 98ce858
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
30 changes: 22 additions & 8 deletions pyo3-macros-backend/src/pyclass.rs
Expand Up @@ -1172,14 +1172,28 @@ fn impl_complex_enum_tuple_variant_match_args(
variant_cls_type: &syn::Type,
field_names: &mut Vec<Ident>,
) -> Result<(MethodAndMethodDef, syn::ImplItemConst)> {
let args_tp = field_names.iter().map(|_| {
quote! { &'static str }
});

let match_args_const_impl: syn::ImplItemConst = parse_quote! {
const __match_args__: ( #(#args_tp),* ) = (
#(stringify!(#field_names),)*
);
let match_args_const_impl: syn::ImplItemConst = match field_names.len() {
// This covers the case where the tuple variant has no fields (valid Rust)
0 => parse_quote! {
const __match_args__: () = ();
},
1 => {
let ident = &field_names[0];
// We need the trailing comma to make it a tuple
parse_quote! {
const __match_args__: (&'static str ,) = (stringify!(#ident) , );
}
}
_ => {
let args_tp = field_names.iter().map(|_| {
quote! { &'static str }
});
parse_quote! {
const __match_args__: ( #(#args_tp),* ) = (
#(stringify!(#field_names),)*
);
}
}
};

let spec = ConstSpec {
Expand Down
7 changes: 7 additions & 0 deletions pytests/src/enums.rs
Expand Up @@ -8,6 +8,7 @@ use pyo3::{
pub fn enums(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<SimpleEnum>()?;
m.add_class::<ComplexEnum>()?;
m.add_class::<SimpleTupleEnum>()?;
m.add_class::<TupleEnum>()?;
m.add_class::<MixedComplexEnum>()?;
m.add_wrapped(wrap_pyfunction_bound!(do_simple_stuff))?;
Expand Down Expand Up @@ -84,6 +85,12 @@ pub fn do_complex_stuff(thing: &ComplexEnum) -> ComplexEnum {
}
}

#[pyclass]
enum SimpleTupleEnum {
Int(i32),
Str(String),
}

#[pyclass]
pub enum TupleEnum {
Full(i32, f64, bool),
Expand Down
17 changes: 17 additions & 0 deletions pytests/tests/test_enums_match.py
Expand Up @@ -96,6 +96,23 @@ def test_tuple_enum_match_statement(variant: enums.TupleEnum):
assert False


@pytest.mark.parametrize(
"variant",
[
enums.SimpleTupleEnum.Int(42),
enums.SimpleTupleEnum.Str("hello"),
],
)
def test_simple_tuple_enum_match_statement(variant: enums.SimpleTupleEnum):
match variant:
case enums.SimpleTupleEnum.Int(x):
assert x == 42
case enums.SimpleTupleEnum.Str(x):
assert x == "hello"
case _:
assert False


@pytest.mark.parametrize(
"variant",
[
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/invalid_pyclass_enum.stderr
Expand Up @@ -25,7 +25,7 @@ error: Unit variant `UnitVariant` is not yet supported in a complex enum
| ^^^^^^^^^^^

error: `constructor` can't be used on a simple enum variant
--> tests/ui/invalid_pyclass_enum.rs:32:12
--> tests/ui/invalid_pyclass_enum.rs:26:12
|
32 | #[pyo3(constructor = (a, b))]
26 | #[pyo3(constructor = (a, b))]
| ^^^^^^^^^^^

0 comments on commit 98ce858

Please sign in to comment.