Skip to content

Commit 7e44c1d

Browse files
Icxoludavidhewitt
authored andcommitted
fix complex enum __qualname__ not using python name (#5815)
1 parent 75abd86 commit 7e44c1d

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

newsfragments/5815.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fix complex enum `__qualname__` not using python name

pyo3-macros-backend/src/pyclass.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -823,12 +823,32 @@ struct PyClassEnumStructVariant<'a> {
823823
options: EnumVariantPyO3Options,
824824
}
825825

826+
impl PyClassEnumStructVariant<'_> {
827+
fn python_name(&self) -> Cow<'_, syn::Ident> {
828+
self.options
829+
.name
830+
.as_ref()
831+
.map(|name_attr| Cow::Borrowed(&name_attr.value.0))
832+
.unwrap_or_else(|| Cow::Owned(self.ident.unraw()))
833+
}
834+
}
835+
826836
struct PyClassEnumTupleVariant<'a> {
827837
ident: &'a syn::Ident,
828838
fields: Vec<PyClassEnumVariantUnnamedField<'a>>,
829839
options: EnumVariantPyO3Options,
830840
}
831841

842+
impl PyClassEnumTupleVariant<'_> {
843+
fn python_name(&self) -> Cow<'_, syn::Ident> {
844+
self.options
845+
.name
846+
.as_ref()
847+
.map(|name_attr| Cow::Borrowed(&name_attr.value.0))
848+
.unwrap_or_else(|| Cow::Owned(self.ident.unraw()))
849+
}
850+
}
851+
832852
struct PyClassEnumVariantNamedField<'a> {
833853
ident: &'a syn::Ident,
834854
ty: &'a syn::Type,
@@ -1288,7 +1308,7 @@ fn impl_complex_enum(
12881308
variant_cls_pytypeinfos.push(variant_cls_pytypeinfo);
12891309

12901310
let (variant_cls_impl, field_getters, mut slots) =
1291-
impl_complex_enum_variant_cls(cls, &variant, ctx)?;
1311+
impl_complex_enum_variant_cls(cls, &args, &variant, ctx)?;
12921312
variant_cls_impls.push(variant_cls_impl);
12931313

12941314
let variant_new = complex_enum_variant_new(cls, variant, ctx)?;
@@ -1341,15 +1361,16 @@ fn impl_complex_enum(
13411361

13421362
fn impl_complex_enum_variant_cls(
13431363
enum_name: &syn::Ident,
1364+
args: &PyClassArgs,
13441365
variant: &PyClassEnumVariant<'_>,
13451366
ctx: &Ctx,
13461367
) -> Result<(TokenStream, Vec<MethodAndMethodDef>, Vec<MethodAndSlotDef>)> {
13471368
match variant {
13481369
PyClassEnumVariant::Struct(struct_variant) => {
1349-
impl_complex_enum_struct_variant_cls(enum_name, struct_variant, ctx)
1370+
impl_complex_enum_struct_variant_cls(enum_name, args, struct_variant, ctx)
13501371
}
13511372
PyClassEnumVariant::Tuple(tuple_variant) => {
1352-
impl_complex_enum_tuple_variant_cls(enum_name, tuple_variant, ctx)
1373+
impl_complex_enum_tuple_variant_cls(enum_name, args, tuple_variant, ctx)
13531374
}
13541375
}
13551376
}
@@ -1406,6 +1427,7 @@ fn impl_complex_enum_variant_match_args(
14061427

14071428
fn impl_complex_enum_struct_variant_cls(
14081429
enum_name: &syn::Ident,
1430+
args: &PyClassArgs,
14091431
variant: &PyClassEnumStructVariant<'_>,
14101432
ctx: &Ctx,
14111433
) -> Result<(TokenStream, Vec<MethodAndMethodDef>, Vec<MethodAndSlotDef>)> {
@@ -1452,8 +1474,12 @@ fn impl_complex_enum_struct_variant_cls(
14521474
field_getter_impls.push(field_getter_impl);
14531475
}
14541476

1455-
let (qualname, qualname_impl) =
1456-
impl_complex_enum_variant_qualname(enum_name, variant_ident, &variant_cls_type, ctx)?;
1477+
let (qualname, qualname_impl) = impl_complex_enum_variant_qualname(
1478+
&get_class_python_name(enum_name, args),
1479+
&variant.python_name(),
1480+
&variant_cls_type,
1481+
ctx,
1482+
)?;
14571483

14581484
field_getters.push(qualname);
14591485

@@ -1624,6 +1650,7 @@ fn impl_complex_enum_tuple_variant_getitem(
16241650

16251651
fn impl_complex_enum_tuple_variant_cls(
16261652
enum_name: &syn::Ident,
1653+
args: &PyClassArgs,
16271654
variant: &PyClassEnumTupleVariant<'_>,
16281655
ctx: &Ctx,
16291656
) -> Result<(TokenStream, Vec<MethodAndMethodDef>, Vec<MethodAndSlotDef>)> {
@@ -1648,8 +1675,12 @@ fn impl_complex_enum_tuple_variant_cls(
16481675
&mut field_types,
16491676
)?;
16501677

1651-
let (qualname, qualname_impl) =
1652-
impl_complex_enum_variant_qualname(enum_name, variant_ident, &variant_cls_type, ctx)?;
1678+
let (qualname, qualname_impl) = impl_complex_enum_variant_qualname(
1679+
&get_class_python_name(enum_name, args),
1680+
&variant.python_name(),
1681+
&variant_cls_type,
1682+
ctx,
1683+
)?;
16531684

16541685
field_getters.push(qualname);
16551686

tests/test_enum.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,21 @@ fn complex_enum_variant_qualname() {
419419
py_assert!(py, cls, "cls.B.__qualname__ == 'ComplexEnum.B'");
420420
});
421421
}
422+
423+
#[test]
424+
fn complex_enum_renamed_variant_qualname() {
425+
#[pyclass(name = "ComplexEnum", skip_from_py_object)]
426+
pub enum PyComplexEnum {
427+
#[pyo3(name = "A")]
428+
PyA(i32),
429+
B {
430+
msg: String,
431+
},
432+
}
433+
434+
Python::attach(|py| {
435+
let cls = py.get_type::<PyComplexEnum>();
436+
py_assert!(py, cls, "cls.A.__qualname__ == 'ComplexEnum.A'");
437+
py_assert!(py, cls, "cls.B.__qualname__ == 'ComplexEnum.B'");
438+
});
439+
}

0 commit comments

Comments
 (0)