Coverage for src / invariant / ops / stdlib.py: 100.00%
25 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-03 19:52 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-03 19:52 +0000
1"""Standard operations library for basic data manipulation."""
3from typing import Any
6def identity(value: Any) -> Any:
7 """Identity operation: returns the input unchanged.
9 Args:
10 value: Any cacheable value.
12 Returns:
13 The input value unchanged.
14 """
15 return value
18def add(a: int, b: int) -> int:
19 """Add two integers.
21 Args:
22 a: First integer.
23 b: Second integer.
25 Returns:
26 Sum of a and b.
27 """
28 return a + b
31def multiply(a: int, b: int) -> int:
32 """Multiply two integers.
34 Args:
35 a: First integer.
36 b: Second integer.
38 Returns:
39 Product of a and b.
40 """
41 return a * b
44def dict_get(dict_obj: dict[str, Any], key: str) -> Any:
45 """Extract a value from a dictionary.
47 Args:
48 dict_obj: Dictionary object.
49 key: String key to look up.
51 Returns:
52 The value at the specified key in the dictionary.
54 Raises:
55 KeyError: If key not in dictionary.
56 TypeError: If dict_obj is not a dict.
57 """
58 if not isinstance(dict_obj, dict):
59 raise TypeError(f"dict_get op requires dict, got {type(dict_obj)}")
61 if key not in dict_obj:
62 raise KeyError(f"Key '{key}' not found in dictionary")
64 return dict_obj[key]
67def make_dict(**kwargs: Any) -> dict[str, Any]:
68 """Construct a dictionary from resolved parameters.
70 This operation collects all resolved parameters (which may have been
71 constructed using ref() and cel() markers) into a new dictionary artifact.
73 Args:
74 **kwargs: Any number of key-value pairs. Keys must be strings.
75 Values can be any cacheable type (resolved from ref/cel markers).
77 Returns:
78 A dictionary containing all the key-value pairs from kwargs.
80 Example:
81 Node(
82 op_name="stdlib:make_dict",
83 params={"width": cel("bg.width"), "color": ref("fg_color")},
84 deps=["bg", "fg_color"],
85 )
86 # Returns: {"width": 144, "color": "#ff0000"}
87 """
88 return dict(kwargs)
91def make_list(items: list[Any]) -> list[Any]:
92 """Construct a list from resolved items.
94 This operation takes a list parameter (which may contain ref() and cel()
95 markers that get resolved during parameter resolution) and returns it as
96 a new list artifact.
98 Args:
99 items: A list of cacheable values (resolved from ref/cel markers).
101 Returns:
102 A list containing all the resolved items.
104 Example:
105 Node(
106 op_name="stdlib:make_list",
107 params={"items": [ref("a"), ref("b"), cel("c + 1")]},
108 deps=["a", "b", "c"],
109 )
110 # Returns: [<resolved a>, <resolved b>, <resolved c+1>]
111 """
112 return list(items)
115def coalesce(values: list[Any]) -> Any:
116 """Return the first non-None value from a list of candidates.
118 Args:
119 values: Candidate values in priority order.
121 Returns:
122 The first value that is not None, or None when all candidates are None.
123 """
124 if not isinstance(values, list):
125 raise TypeError(f"coalesce op requires list, got {type(values)}")
127 for value in values:
128 if value is not None:
129 return value
130 return None
133# Package of standard operations
134OPS: dict[str, Any] = {
135 "identity": identity,
136 "add": add,
137 "multiply": multiply,
138 "dict_get": dict_get,
139 "make_dict": make_dict,
140 "make_list": make_list,
141 "coalesce": coalesce,
142}