Coverage for src/invariant/ops/stdlib.py: 100.00%

1"""Standard operations library for basic data manipulation."""

2

3 from typing import Any

4

5

6 def identity(value: Any) -> Any:

7 """Identity operation: returns the input unchanged.

8

9 Args:

10 value: Any cacheable value.

11

12 Returns:

13 The input value unchanged.

14 """

15 return value

16

17

18 def add(a: int, b: int) -> int:

19 """Add two integers.

20

21 Args:

22 a: First integer.

23 b: Second integer.

24

25 Returns:

26 Sum of a and b.

27 """

28 return a + b

29

30

31 def multiply(a: int, b: int) -> int:

32 """Multiply two integers.

33

34 Args:

35 a: First integer.

36 b: Second integer.

37

38 Returns:

39 Product of a and b.

40 """

41 return a * b

42

43

44 def dict_get(dict_obj: dict[str, Any], key: str) -> Any:

45 """Extract a value from a dictionary.

46

47 Args:

48 dict_obj: Dictionary object.

49 key: String key to look up.

50

51 Returns:

52 The value at the specified key in the dictionary.

53

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)}")

60

61 if key not in dict_obj:

62 raise KeyError(f"Key '{key}' not found in dictionary")

63

64 return dict_obj[key]

65

66

67 def make_dict(**kwargs: Any) -> dict[str, Any]:

68 """Construct a dictionary from resolved parameters.

69

70 This operation collects all resolved parameters (which may have been

71 constructed using ref() and cel() markers) into a new dictionary artifact.

72

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).

76

77 Returns:

78 A dictionary containing all the key-value pairs from kwargs.

79

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)

89

90

91 def make_list(items: list[Any]) -> list[Any]:

92 """Construct a list from resolved items.

93

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.

97

98 Args:

99 items: A list of cacheable values (resolved from ref/cel markers).

100

101 Returns:

102 A list containing all the resolved items.

103

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)

113

114

115# Package of standard operations

116 OPS: dict[str, Any] = {

117 "identity": identity,

118 "add": add,

119 "multiply": multiply,

120 "dict_get": dict_get,

121 "make_dict": make_dict,

122 "make_list": make_list,

123}