examples.31_dataclass_integration

Demonstrates how to use ConstrainedValue types (like EnumValue and RangeValue) inside a dataclass-style configuration object to validate and normalize input data.

This example shows:
  • How to wrap constrained values within a dataclass.
  • How to perform field-by-field validation during initialization.
  • How to return a tuple of (ok, result) indicating success or errors.
Run directly:

python examples/31_dataclass_integration.py

Expected output:

OK: True WidgetConfig(name='Gizmo', color='green', slots=4) OK2: False {'color': "Value must be one of ('red', 'green', 'blue'), got purple", 'slots': 'Value must be greater than or equal to 1, got 0'}

  1"""Demonstrates how to use :class:`ConstrainedValue` types (like
  2:class:`EnumValue` and :class:`RangeValue`) inside a dataclass-style
  3configuration object to validate and normalize input data.
  4
  5This example shows:
  6  * How to wrap constrained values within a dataclass.
  7  * How to perform field-by-field validation during initialization.
  8  * How to return a tuple of `(ok, result)` indicating success or errors.
  9
 10Run directly:
 11
 12    python examples/31_dataclass_integration.py
 13
 14Expected output:
 15
 16    OK: True WidgetConfig(name='Gizmo', color='green', slots=4)
 17    OK2: False {'color': "Value must be one of ('red', 'green', 'blue'), got purple",
 18         'slots': 'Value must be greater than or equal to 1, got 0'}
 19"""
 20
 21import sys
 22import pathlib
 23from dataclasses import dataclass
 24from enum import Enum
 25from typing import Any, Dict, Tuple, Union
 26
 27# ---------------------------------------------------------------------------
 28# Make repo root importable when running this file directly
 29# ---------------------------------------------------------------------------
 30sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
 31
 32from constrained_values import EnumValue, RangeValue
 33
 34
 35class Color(Enum):
 36    """An enumeration of valid widget colors."""
 37    RED = "red"
 38    GREEN = "green"
 39    BLUE = "blue"
 40
 41
 42@dataclass
 43class WidgetConfig:
 44    """A dataclass-like configuration object that uses constrained fields.
 45
 46    Attributes:
 47        name: The name of the widget (unvalidated string).
 48        color: Validated color, as a :class:`Color` enum member.
 49        slots: Validated integer slot count between 1 and 16.
 50    """
 51
 52    name: str
 53    color: Any
 54    slots: Any
 55
 56    @classmethod
 57    def from_input(cls, name: str, color: Any, slots: Any) -> Tuple[bool, Union["WidgetConfig", Dict[str, str]]]:
 58        """Validate input and construct a `WidgetConfig` instance.
 59
 60        Wraps input fields in :class:`ConstrainedValue` types to ensure
 61        they meet constraints before constructing the dataclass.
 62
 63        Args:
 64            name: The widget's name (any string).
 65            color: The color input (enum value or string).
 66            slots: The slot count to validate (integer).
 67
 68        Returns:
 69            Tuple[bool, Union[WidgetConfig, Dict[str, str]]]:
 70                * `(True, WidgetConfig)` if all validations succeed.
 71                * `(False, errors_dict)` if one or more validations fail.
 72        """
 73        cv_color = EnumValue(color, Color)
 74        cv_slots = RangeValue(slots, 1, 16)
 75
 76        ok = cv_color.ok and cv_slots.ok
 77        if not ok:
 78            errors: Dict[str, str] = {}
 79            if not cv_color.ok:
 80                errors["color"] = cv_color.details
 81            if not cv_slots.ok:
 82                errors["slots"] = cv_slots.details
 83            return False, errors
 84
 85        return True, cls(name=name, color=cv_color.value, slots=cv_slots.value)
 86
 87
 88def main() -> None:
 89    """Run the dataclass integration demonstration.
 90
 91    Steps:
 92        1. Construct a valid configuration using `"Gizmo", "green", 4"`.
 93        2. Attempt to construct an invalid configuration with `"purple", 0"`.
 94        3. Print the success flag and resulting object or error dictionary.
 95
 96    Prints:
 97        * `"OK: True WidgetConfig(name='Gizmo', color='green', slots=4)"`
 98        * `"OK2: False {'color': "Value must be one of ('red', 'green', 'blue'),
 99        *        got purple", 'slots': 'Value must be greater than or equal to 1, got 0'}"`
100    """
101    ok, res = WidgetConfig.from_input("Gizmo", "green", 4)
102    print("OK:", ok, res)
103
104    ok2, res2 = WidgetConfig.from_input("Oops", "purple", 0)
105    print("OK2:", ok2, res2)
106
107
108if __name__ == "__main__":
109    main()
class Color(enum.Enum):
36class Color(Enum):
37    """An enumeration of valid widget colors."""
38    RED = "red"
39    GREEN = "green"
40    BLUE = "blue"

An enumeration of valid widget colors.

RED = <Color.RED: 'red'>
GREEN = <Color.GREEN: 'green'>
BLUE = <Color.BLUE: 'blue'>
Inherited Members
enum.Enum
name
value
@dataclass
class WidgetConfig:
43@dataclass
44class WidgetConfig:
45    """A dataclass-like configuration object that uses constrained fields.
46
47    Attributes:
48        name: The name of the widget (unvalidated string).
49        color: Validated color, as a :class:`Color` enum member.
50        slots: Validated integer slot count between 1 and 16.
51    """
52
53    name: str
54    color: Any
55    slots: Any
56
57    @classmethod
58    def from_input(cls, name: str, color: Any, slots: Any) -> Tuple[bool, Union["WidgetConfig", Dict[str, str]]]:
59        """Validate input and construct a `WidgetConfig` instance.
60
61        Wraps input fields in :class:`ConstrainedValue` types to ensure
62        they meet constraints before constructing the dataclass.
63
64        Args:
65            name: The widget's name (any string).
66            color: The color input (enum value or string).
67            slots: The slot count to validate (integer).
68
69        Returns:
70            Tuple[bool, Union[WidgetConfig, Dict[str, str]]]:
71                * `(True, WidgetConfig)` if all validations succeed.
72                * `(False, errors_dict)` if one or more validations fail.
73        """
74        cv_color = EnumValue(color, Color)
75        cv_slots = RangeValue(slots, 1, 16)
76
77        ok = cv_color.ok and cv_slots.ok
78        if not ok:
79            errors: Dict[str, str] = {}
80            if not cv_color.ok:
81                errors["color"] = cv_color.details
82            if not cv_slots.ok:
83                errors["slots"] = cv_slots.details
84            return False, errors
85
86        return True, cls(name=name, color=cv_color.value, slots=cv_slots.value)

A dataclass-like configuration object that uses constrained fields.

Attributes:
  • name: The name of the widget (unvalidated string).
  • color: Validated color, as a Color enum member.
  • slots: Validated integer slot count between 1 and 16.
WidgetConfig(name: str, color: Any, slots: Any)
name : str
color : Any
slots : Any
@classmethod
def from_input( cls, name: str, color: Any, slots: Any) -> Tuple[bool, Union[examples.31_dataclass_integration.WidgetConfig, Dict[str, str]]]:
57    @classmethod
58    def from_input(cls, name: str, color: Any, slots: Any) -> Tuple[bool, Union["WidgetConfig", Dict[str, str]]]:
59        """Validate input and construct a `WidgetConfig` instance.
60
61        Wraps input fields in :class:`ConstrainedValue` types to ensure
62        they meet constraints before constructing the dataclass.
63
64        Args:
65            name: The widget's name (any string).
66            color: The color input (enum value or string).
67            slots: The slot count to validate (integer).
68
69        Returns:
70            Tuple[bool, Union[WidgetConfig, Dict[str, str]]]:
71                * `(True, WidgetConfig)` if all validations succeed.
72                * `(False, errors_dict)` if one or more validations fail.
73        """
74        cv_color = EnumValue(color, Color)
75        cv_slots = RangeValue(slots, 1, 16)
76
77        ok = cv_color.ok and cv_slots.ok
78        if not ok:
79            errors: Dict[str, str] = {}
80            if not cv_color.ok:
81                errors["color"] = cv_color.details
82            if not cv_slots.ok:
83                errors["slots"] = cv_slots.details
84            return False, errors
85
86        return True, cls(name=name, color=cv_color.value, slots=cv_slots.value)

Validate input and construct a WidgetConfig instance.

Wraps input fields in ConstrainedValue types to ensure they meet constraints before constructing the dataclass.

Arguments:
  • name: The widget's name (any string).
  • color: The color input (enum value or string).
  • slots: The slot count to validate (integer).
Returns:

Tuple[bool, Union[WidgetConfig, Dict[str, str]]]: * (True, WidgetConfig) if all validations succeed. * (False, errors_dict) if one or more validations fail.

def main() -> None:
 89def main() -> None:
 90    """Run the dataclass integration demonstration.
 91
 92    Steps:
 93        1. Construct a valid configuration using `"Gizmo", "green", 4"`.
 94        2. Attempt to construct an invalid configuration with `"purple", 0"`.
 95        3. Print the success flag and resulting object or error dictionary.
 96
 97    Prints:
 98        * `"OK: True WidgetConfig(name='Gizmo', color='green', slots=4)"`
 99        * `"OK2: False {'color': "Value must be one of ('red', 'green', 'blue'),
100        *        got purple", 'slots': 'Value must be greater than or equal to 1, got 0'}"`
101    """
102    ok, res = WidgetConfig.from_input("Gizmo", "green", 4)
103    print("OK:", ok, res)
104
105    ok2, res2 = WidgetConfig.from_input("Oops", "purple", 0)
106    print("OK2:", ok2, res2)

Run the dataclass integration demonstration.

Steps:
  1. Construct a valid configuration using "Gizmo", "green", 4".
  2. Attempt to construct an invalid configuration with "purple", 0".
  3. Print the success flag and resulting object or error dictionary.
Prints:
  • "OK: True WidgetConfig(name='Gizmo', color='green', slots=4)"
  • `"OK2: False {'color': "Value must be one of ('red', 'green', 'blue'),
  • got purple", 'slots': 'Value must be greater than or equal to 1, got 0'}"`