examples.09_chained_transforms

Demonstrates how multiple transformation steps can be chained together before final validation within a ConstrainedValue pipeline.

This example shows:
  • How multiple TransformationStrategy instances operate sequentially.
  • How each step modifies the intermediate value.
  • How a RangeValidationStrategy validates the final result.
  • How success and failure propagate through the pipeline.
Run directly:

python examples/09_chained_transforms.py

Expected output:

ok: OK 10 bad: EXCEPTION Value must be less than or equal to 50, got 54 None

  1"""Demonstrates how multiple transformation steps can be chained together
  2before final validation within a `ConstrainedValue` pipeline.
  3
  4This example shows:
  5  * How multiple `TransformationStrategy` instances operate sequentially.
  6  * How each step modifies the intermediate value.
  7  * How a `RangeValidationStrategy` validates the final result.
  8  * How success and failure propagate through the pipeline.
  9
 10Run directly:
 11
 12    python examples/09_chained_transforms.py
 13
 14Expected output:
 15
 16    ok: OK 10
 17    bad: EXCEPTION Value must be less than or equal to 50, got 54 None
 18"""
 19
 20import sys
 21import pathlib
 22from typing import List
 23
 24# ---------------------------------------------------------------------------
 25# Make repo root importable when running this file directly
 26# ---------------------------------------------------------------------------
 27sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
 28
 29from constrained_values import Response, Status, RangeValidationStrategy
 30from constrained_values.value import TransformationStrategy, ConstrainedValue, PipeLineStrategy
 31
 32
 33class Inc(TransformationStrategy[int, int]):
 34    """A transformation strategy that increments the value by one."""
 35
 36    def transform(self, value: int) -> Response[int]:
 37        """Increment the given value.
 38
 39        Args:
 40            value: The integer to increment.
 41
 42        Returns:
 43            Response[int]: Contains:
 44                * `status = Status.OK`
 45                * `details = "inc"`
 46                * `value = value + 1`
 47        """
 48        return Response(status=Status.OK, details="inc", value=value + 1)
 49
 50
 51class Double(TransformationStrategy[int, int]):
 52    """A transformation strategy that doubles the input value."""
 53
 54    def transform(self, value: int) -> Response[int]:
 55        """Multiply the value by two.
 56
 57        Args:
 58            value: The integer to double.
 59
 60        Returns:
 61            Response[int]: Contains:
 62                * `status = Status.OK`
 63                * `details = "double"`
 64                * `value = value * 2`
 65        """
 66        return Response(status=Status.OK, details="double", value=value * 2)
 67
 68
 69class Chained(ConstrainedValue[int]):
 70    """A `ConstrainedValue[int]` that chains multiple transformation steps.
 71
 72    The transformation pipeline:
 73        1. `Inc()` – adds 1.
 74        2. `Double()` – multiplies by 2.
 75        3. `RangeValidationStrategy(10, 50)` – ensures the final value is within range.
 76
 77    This shows how complex constraints can be composed using multiple
 78    reusable strategies.
 79    """
 80
 81    def get_strategies(self) -> List[PipeLineStrategy]:
 82        """Return the chained transformation and validation pipeline."""
 83        return [Inc(), Double(), RangeValidationStrategy(10, 50)]
 84
 85
 86def main() -> None:
 87    """Run the chained transformation demonstration.
 88
 89    Creates two `Chained` constrained values:
 90      * One with input `4` → (4 + 1) * 2 = 10 → OK.
 91      * One with input `26` → (26 + 1) * 2 = 54 → out of range → EXCEPTION.
 92
 93    Prints:
 94        * `"ok: OK 10"`
 95        * `"bad: EXCEPTION Value must be less than or equal to 50, got 54 None"`
 96    """
 97    ok = Chained(4)    # (4+1)*2 = 10 → OK
 98    bad = Chained(26)  # (26+1)*2 = 54 → out of range
 99    print("ok:", ok.status.name, ok.value)
100    print("bad:", bad.status.name, bad.details, bad.value)
101
102
103if __name__ == "__main__":
104    main()
class Inc(constrained_values.value.TransformationStrategy[int, int]):
34class Inc(TransformationStrategy[int, int]):
35    """A transformation strategy that increments the value by one."""
36
37    def transform(self, value: int) -> Response[int]:
38        """Increment the given value.
39
40        Args:
41            value: The integer to increment.
42
43        Returns:
44            Response[int]: Contains:
45                * `status = Status.OK`
46                * `details = "inc"`
47                * `value = value + 1`
48        """
49        return Response(status=Status.OK, details="inc", value=value + 1)

A transformation strategy that increments the value by one.

def transform(self, value: int) -> constrained_values.Response[int]:
37    def transform(self, value: int) -> Response[int]:
38        """Increment the given value.
39
40        Args:
41            value: The integer to increment.
42
43        Returns:
44            Response[int]: Contains:
45                * `status = Status.OK`
46                * `details = "inc"`
47                * `value = value + 1`
48        """
49        return Response(status=Status.OK, details="inc", value=value + 1)

Increment the given value.

Arguments:
  • value: The integer to increment.
Returns:

Response[int]: Contains: * status = Status.OK * details = "inc" * value = value + 1

class Double(constrained_values.value.TransformationStrategy[int, int]):
52class Double(TransformationStrategy[int, int]):
53    """A transformation strategy that doubles the input value."""
54
55    def transform(self, value: int) -> Response[int]:
56        """Multiply the value by two.
57
58        Args:
59            value: The integer to double.
60
61        Returns:
62            Response[int]: Contains:
63                * `status = Status.OK`
64                * `details = "double"`
65                * `value = value * 2`
66        """
67        return Response(status=Status.OK, details="double", value=value * 2)

A transformation strategy that doubles the input value.

def transform(self, value: int) -> constrained_values.Response[int]:
55    def transform(self, value: int) -> Response[int]:
56        """Multiply the value by two.
57
58        Args:
59            value: The integer to double.
60
61        Returns:
62            Response[int]: Contains:
63                * `status = Status.OK`
64                * `details = "double"`
65                * `value = value * 2`
66        """
67        return Response(status=Status.OK, details="double", value=value * 2)

Multiply the value by two.

Arguments:
  • value: The integer to double.
Returns:

Response[int]: Contains: * status = Status.OK * details = "double" * value = value * 2

class Chained(constrained_values.value.ConstrainedValue[int]):
70class Chained(ConstrainedValue[int]):
71    """A `ConstrainedValue[int]` that chains multiple transformation steps.
72
73    The transformation pipeline:
74        1. `Inc()` – adds 1.
75        2. `Double()` – multiplies by 2.
76        3. `RangeValidationStrategy(10, 50)` – ensures the final value is within range.
77
78    This shows how complex constraints can be composed using multiple
79    reusable strategies.
80    """
81
82    def get_strategies(self) -> List[PipeLineStrategy]:
83        """Return the chained transformation and validation pipeline."""
84        return [Inc(), Double(), RangeValidationStrategy(10, 50)]

A ConstrainedValue[int] that chains multiple transformation steps.

The transformation pipeline:
  1. Inc() – adds 1.
  2. Double() – multiplies by 2.
  3. RangeValidationStrategy(10, 50) – ensures the final value is within range.

This shows how complex constraints can be composed using multiple reusable strategies.

def get_strategies(self) -> List[constrained_values.value.PipeLineStrategy]:
82    def get_strategies(self) -> List[PipeLineStrategy]:
83        """Return the chained transformation and validation pipeline."""
84        return [Inc(), Double(), RangeValidationStrategy(10, 50)]

Return the chained transformation and validation pipeline.

Inherited Members
constrained_values.value.ConstrainedValue
ConstrainedValue
status
details
value
unwrap
ok
def main() -> None:
 87def main() -> None:
 88    """Run the chained transformation demonstration.
 89
 90    Creates two `Chained` constrained values:
 91      * One with input `4` → (4 + 1) * 2 = 10 → OK.
 92      * One with input `26` → (26 + 1) * 2 = 54 → out of range → EXCEPTION.
 93
 94    Prints:
 95        * `"ok: OK 10"`
 96        * `"bad: EXCEPTION Value must be less than or equal to 50, got 54 None"`
 97    """
 98    ok = Chained(4)    # (4+1)*2 = 10 → OK
 99    bad = Chained(26)  # (26+1)*2 = 54 → out of range
100    print("ok:", ok.status.name, ok.value)
101    print("bad:", bad.status.name, bad.details, bad.value)

Run the chained transformation demonstration.

Creates two Chained constrained values:

  • One with input 4 → (4 + 1) * 2 = 10 → OK.
  • One with input 26 → (26 + 1) * 2 = 54 → out of range → EXCEPTION.
Prints:
  • "ok: OK 10"
  • "bad: EXCEPTION Value must be less than or equal to 50, got 54 None"