diff --git a/questionpy/form/_dsl.py b/questionpy/form/_dsl.py index 9d5b2559..252a8775 100644 --- a/questionpy/form/_dsl.py +++ b/questionpy/form/_dsl.py @@ -580,24 +580,26 @@ def select( ) -def option(label: str, *, selected: bool = False) -> _OptionInfo: +def option(label: str, *, selected: bool = False, value: str | None = None) -> _OptionInfo: """Adds an option to an [`OptionEnum`][questionpy.form.OptionEnum]. Args: label: Text describing the option, shown verbatim. selected: Default state of the option. + value: By default, the name of the option is used as its value as well. You can set a different value here, + which will then be used in rendering as well as (de)serialization. Returns: An internal object containing metadata about the option. Examples: >>> class ColorEnum(OptionEnum): - ... RED = option("Red") - ... GREEN = option("Green") - ... BLUE = option("Blue") + ... RED = option("Red", value="R") + ... GREEN = option("Green", value="G") + ... BLUE = option("Blue", value="B") ... NONE = option("None", selected=True) """ - return _OptionInfo(label, selected) + return _OptionInfo(label, selected, value=value) @overload diff --git a/questionpy/form/_model.py b/questionpy/form/_model.py index 100779f4..d9641b9e 100644 --- a/questionpy/form/_model.py +++ b/questionpy/form/_model.py @@ -21,7 +21,7 @@ class _OptionInfo: label: str selected: bool value: str | None = None - """Set by `OptionEnum.__init__` because __set_name__ doesn't get called for enum members.""" + """If None, set to the name by `OptionEnum.__init__` because __set_name__ doesn't get called for enum members.""" class OptionEnum(Enum): @@ -32,7 +32,10 @@ class OptionEnum(Enum): def __init__(self, option: _OptionInfo) -> None: super().__init__() - self._value_ = option.value = self.name + if option.value is None: + option.value = self.name + + self._value_ = option.value self.label = option.label self.selected = option.selected diff --git a/tests/questionpy/form/test_dsl.py b/tests/questionpy/form/test_dsl.py index ef1db401..43214c8a 100644 --- a/tests/questionpy/form/test_dsl.py +++ b/tests/questionpy/form/test_dsl.py @@ -12,6 +12,7 @@ class MyOptionEnum(form.OptionEnum): OPT_1 = form.option("Label 1") + OPT_2 = form.option("Label 2", value="b") class SimpleFormModel(form.FormModel): @@ -107,7 +108,7 @@ def test_should_raise_validation_error_when_required_option_is_missing() -> None form.RadioGroupElement( name="field", label="Label", - options=[form.Option(label="Label 1", value="OPT_1")], + options=[form.Option(label="Label 1", value="OPT_1"), form.Option(label="Label 2", value="b")], required=True, help="Help", ) @@ -119,7 +120,7 @@ def test_should_raise_validation_error_when_required_option_is_missing() -> None form.SelectElement( name="field", label="Label", - options=[form.Option(label="Label 1", value="OPT_1")], + options=[form.Option(label="Label 1", value="OPT_1"), form.Option(label="Label 2", value="b")], required=True, multiple=True, help="Help",