Default values in enum struct-variants
Hello everyone,
Thank you for your great work here. Our project makes extensive use of struct enum variants. However, we have many variants which should have default values: some of those variants are Option<...> and should default to None if they are not specified. This behavior would be similar to the kwargs in functions, where a default is used if the value is not specified.
Currently, for this enum:
#[pyclass]
enum Thing
A {
x: Option<i32>,
y: i32,
z: i32,
}
}
I would use it like this: Thing.A(x=None, y=5, z=1).
However, setting x to None manually makes the code more verbose. It would be easier for the user to do the following:
#[pyclass]
enum Thing
A {
#[pyo3(default = None)] # <----- Add something like this?
x: Option<i32>,
y: i32,
#[pyo3(default = 1)]
z: i32
}
}
Which would be used like this: Thing.A(y=5) where x=None and z=1.
I am not sure how difficult this is to implement, but it would be much appreciated to have this feature!
How about allowing #[pyo3(signature = ...)] on complex enum variants to specify the constructor signature? Like so:
#[pyclass]
enum Thing
#[pyo3(signature = (x = None, y = 0, z = 1)]
A {
x: Option<i32>,
y: i32,
z: i32,
}
}
This would be comparable to building the class hierarchi manuelly and gives the same control (default, pos/kw only args, ...) as a the constructor for a #[pyclass] struct would. We would also be able to reuse the existing attribute implementation from #[pyfunction]/#[pymethods]. I've experimented with that idea over here https://github.com/Icxolu/pyo3/commit/3e2c41b377d0ed825c33b4a833b01e5aa25bb727
@Icxolu, I think that looks great! Do you plan to open a PR?
Thanks! Glad you like it. Yes, if people think the syntax and functionality proposed above is workable I'll open a PR from that. Given that #[pyo3(signature = ...] is currently only supported on functions (and is most intuitively understand there), I think I'll wait for a few more opinions whether we should reuse it here, or if we perhaps should rename it in this position
(#[pyo3(constructor = ...)], or something like that could also be an option) to make clear what the signature refers to.
I really like it too. And actually, I think it could also make sense to extend this feature to regular struct, to auto-generate constructors in a kind of dataclass-like fashion (but not necessarily in the same PR).