PyDecisionGraph 0.3.2.post1__cp315-cp315-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. decision_graph/__infra__.pxd +1 -0
  2. decision_graph/__init__.pxd +1 -0
  3. decision_graph/__init__.py +39 -0
  4. decision_graph/decision_tree/__init__.pxd +2 -0
  5. decision_graph/decision_tree/__init__.py +85 -0
  6. decision_graph/decision_tree/bake/__infra__.pxd +502 -0
  7. decision_graph/decision_tree/bake/__init__.pxd +502 -0
  8. decision_graph/decision_tree/bake/__init__.py +29 -0
  9. decision_graph/decision_tree/bake/c_action.cp315-win_amd64.pyd +0 -0
  10. decision_graph/decision_tree/bake/c_action.h +324 -0
  11. decision_graph/decision_tree/bake/c_action.pxd +54 -0
  12. decision_graph/decision_tree/bake/c_action.pyi +126 -0
  13. decision_graph/decision_tree/bake/c_action.pyx +65 -0
  14. decision_graph/decision_tree/bake/c_allocator_protocol.cp315-win_amd64.pyd +0 -0
  15. decision_graph/decision_tree/bake/c_allocator_protocol.pxd +24 -0
  16. decision_graph/decision_tree/bake/c_allocator_protocol.pyi +61 -0
  17. decision_graph/decision_tree/bake/c_allocator_protocol.pyx +109 -0
  18. decision_graph/decision_tree/bake/c_bake.cp315-win_amd64.pyd +0 -0
  19. decision_graph/decision_tree/bake/c_bake.h +629 -0
  20. decision_graph/decision_tree/bake/c_bake.pxd +52 -0
  21. decision_graph/decision_tree/bake/c_bake.pyi +151 -0
  22. decision_graph/decision_tree/bake/c_bake.pyx +142 -0
  23. decision_graph/decision_tree/bake/c_collections.cp315-win_amd64.pyd +0 -0
  24. decision_graph/decision_tree/bake/c_collections.h +692 -0
  25. decision_graph/decision_tree/bake/c_collections.pxd +52 -0
  26. decision_graph/decision_tree/bake/c_collections.pyi +193 -0
  27. decision_graph/decision_tree/bake/c_collections.pyx +161 -0
  28. decision_graph/decision_tree/bake/c_const.cp315-win_amd64.pyd +0 -0
  29. decision_graph/decision_tree/bake/c_const.h +395 -0
  30. decision_graph/decision_tree/bake/c_const.pxd +56 -0
  31. decision_graph/decision_tree/bake/c_const.pyi +305 -0
  32. decision_graph/decision_tree/bake/c_const.pyx +278 -0
  33. decision_graph/decision_tree/bake/c_edge.cp315-win_amd64.pyd +0 -0
  34. decision_graph/decision_tree/bake/c_edge.h +511 -0
  35. decision_graph/decision_tree/bake/c_edge.pxd +117 -0
  36. decision_graph/decision_tree/bake/c_edge.pyi +192 -0
  37. decision_graph/decision_tree/bake/c_edge.pyx +270 -0
  38. decision_graph/decision_tree/bake/c_eval.h +848 -0
  39. decision_graph/decision_tree/bake/c_eval.pxd +40 -0
  40. decision_graph/decision_tree/bake/c_expr.cp315-win_amd64.pyd +0 -0
  41. decision_graph/decision_tree/bake/c_expr.h +1900 -0
  42. decision_graph/decision_tree/bake/c_expr.pxd +129 -0
  43. decision_graph/decision_tree/bake/c_expr.pyi +280 -0
  44. decision_graph/decision_tree/bake/c_expr.pyx +272 -0
  45. decision_graph/decision_tree/bake/c_hierarchy.cp315-win_amd64.pyd +0 -0
  46. decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
  47. decision_graph/decision_tree/bake/c_hierarchy.pxd +71 -0
  48. decision_graph/decision_tree/bake/c_hierarchy.pyi +409 -0
  49. decision_graph/decision_tree/bake/c_hierarchy.pyx +277 -0
  50. decision_graph/decision_tree/bake/c_logic_group.cp315-win_amd64.pyd +0 -0
  51. decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
  52. decision_graph/decision_tree/bake/c_logic_group.pxd +162 -0
  53. decision_graph/decision_tree/bake/c_logic_group.pyi +264 -0
  54. decision_graph/decision_tree/bake/c_logic_group.pyx +308 -0
  55. decision_graph/decision_tree/bake/c_node.cp315-win_amd64.pyd +0 -0
  56. decision_graph/decision_tree/bake/c_node.h +2660 -0
  57. decision_graph/decision_tree/bake/c_node.pxd +381 -0
  58. decision_graph/decision_tree/bake/c_node.pyi +438 -0
  59. decision_graph/decision_tree/bake/c_node.pyx +639 -0
  60. decision_graph/decision_tree/bake/c_reconstruct.cp315-win_amd64.pyd +0 -0
  61. decision_graph/decision_tree/bake/c_reconstruct.pxd +63 -0
  62. decision_graph/decision_tree/bake/c_reconstruct.pyi +60 -0
  63. decision_graph/decision_tree/bake/c_reconstruct.pyx +252 -0
  64. decision_graph/decision_tree/bake/c_var.cp315-win_amd64.pyd +0 -0
  65. decision_graph/decision_tree/bake/c_var.h +2054 -0
  66. decision_graph/decision_tree/bake/c_var.pxd +205 -0
  67. decision_graph/decision_tree/bake/c_var.pyi +271 -0
  68. decision_graph/decision_tree/bake/c_var.pyx +228 -0
  69. decision_graph/decision_tree/capi/__infra__.pxd +33 -0
  70. decision_graph/decision_tree/capi/__init__.pxd +33 -0
  71. decision_graph/decision_tree/capi/__init__.py +57 -0
  72. decision_graph/decision_tree/capi/c_abc.cp315-win_amd64.pyd +0 -0
  73. decision_graph/decision_tree/capi/c_abc.pxd +246 -0
  74. decision_graph/decision_tree/capi/c_abc.pyi +770 -0
  75. decision_graph/decision_tree/capi/c_abc.pyx +1532 -0
  76. decision_graph/decision_tree/capi/c_collection.cp315-win_amd64.pyd +0 -0
  77. decision_graph/decision_tree/capi/c_collection.pxd +22 -0
  78. decision_graph/decision_tree/capi/c_collection.pyi +245 -0
  79. decision_graph/decision_tree/capi/c_collection.pyx +138 -0
  80. decision_graph/decision_tree/capi/c_node.cp315-win_amd64.pyd +0 -0
  81. decision_graph/decision_tree/capi/c_node.pxd +95 -0
  82. decision_graph/decision_tree/capi/c_node.pyi +492 -0
  83. decision_graph/decision_tree/capi/c_node.pyx +551 -0
  84. decision_graph/decision_tree/exc.py +189 -0
  85. decision_graph/decision_tree/native/__init__.py +57 -0
  86. decision_graph/decision_tree/native/abc.py +1167 -0
  87. decision_graph/decision_tree/native/collection.py +134 -0
  88. decision_graph/decision_tree/native/node.py +521 -0
  89. decision_graph/includes/decision_graph/decision_tree/bake/c_action.c +16320 -0
  90. decision_graph/includes/decision_graph/decision_tree/bake/c_action.h +324 -0
  91. decision_graph/includes/decision_graph/decision_tree/bake/c_allocator_protocol.c +12473 -0
  92. decision_graph/includes/decision_graph/decision_tree/bake/c_bake.c +16485 -0
  93. decision_graph/includes/decision_graph/decision_tree/bake/c_bake.h +629 -0
  94. decision_graph/includes/decision_graph/decision_tree/bake/c_collections.c +17381 -0
  95. decision_graph/includes/decision_graph/decision_tree/bake/c_collections.h +692 -0
  96. decision_graph/includes/decision_graph/decision_tree/bake/c_const.c +20815 -0
  97. decision_graph/includes/decision_graph/decision_tree/bake/c_const.h +395 -0
  98. decision_graph/includes/decision_graph/decision_tree/bake/c_edge.c +20696 -0
  99. decision_graph/includes/decision_graph/decision_tree/bake/c_edge.h +511 -0
  100. decision_graph/includes/decision_graph/decision_tree/bake/c_eval.h +848 -0
  101. decision_graph/includes/decision_graph/decision_tree/bake/c_expr.c +22065 -0
  102. decision_graph/includes/decision_graph/decision_tree/bake/c_expr.h +1900 -0
  103. decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.c +23267 -0
  104. decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
  105. decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.c +22434 -0
  106. decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
  107. decision_graph/includes/decision_graph/decision_tree/bake/c_node.c +28385 -0
  108. decision_graph/includes/decision_graph/decision_tree/bake/c_node.h +2660 -0
  109. decision_graph/includes/decision_graph/decision_tree/bake/c_reconstruct.c +15955 -0
  110. decision_graph/includes/decision_graph/decision_tree/bake/c_var.c +16881 -0
  111. decision_graph/includes/decision_graph/decision_tree/bake/c_var.h +2054 -0
  112. decision_graph/includes/decision_graph/decision_tree/capi/c_abc.c +59196 -0
  113. decision_graph/includes/decision_graph/decision_tree/capi/c_collection.c +19967 -0
  114. decision_graph/includes/decision_graph/decision_tree/capi/c_node.c +39229 -0
  115. decision_graph/logic_group/__init__.py +25 -0
  116. decision_graph/logic_group/base.py +100 -0
  117. decision_graph/logic_group/pending_request.py +384 -0
  118. decision_graph/webui/__init__.py +24 -0
  119. decision_graph/webui/bake/__init__.py +65 -0
  120. decision_graph/webui/bake/app.py +488 -0
  121. decision_graph/webui/bake/static/d3.v7.min.js +2 -0
  122. decision_graph/webui/bake/static/script.js +1440 -0
  123. decision_graph/webui/bake/static/style.css +920 -0
  124. decision_graph/webui/bake/templates/index.html +183 -0
  125. decision_graph/webui/bake/templates/offline.html +184 -0
  126. decision_graph/webui/capi/__init__.py +54 -0
  127. decision_graph/webui/capi/app.py +366 -0
  128. decision_graph/webui/capi/main.py +53 -0
  129. decision_graph/webui/capi/static/d3.v7.min.js +2 -0
  130. decision_graph/webui/capi/static/script.js +1026 -0
  131. decision_graph/webui/capi/static/style.css +656 -0
  132. decision_graph/webui/capi/templates/index.html +93 -0
  133. decision_graph/webui/capi/templates/offline.html +94 -0
  134. decision_graph/webui/native/__init__.py +54 -0
  135. decision_graph/webui/native/app.py +366 -0
  136. decision_graph/webui/native/main.py +53 -0
  137. decision_graph/webui/native/static/d3.v7.min.js +2 -0
  138. decision_graph/webui/native/static/script.js +1026 -0
  139. decision_graph/webui/native/static/style.css +656 -0
  140. decision_graph/webui/native/templates/index.html +93 -0
  141. decision_graph/webui/native/templates/offline.html +94 -0
  142. pydecisiongraph-0.3.2.post1.dist-info/METADATA +136 -0
  143. pydecisiongraph-0.3.2.post1.dist-info/RECORD +148 -0
  144. pydecisiongraph-0.3.2.post1.dist-info/WHEEL +5 -0
  145. pydecisiongraph-0.3.2.post1.dist-info/licenses/LICENSE +373 -0
  146. pydecisiongraph-0.3.2.post1.dist-info/top_level.txt +2 -0
  147. tests/bake_c_evaluator.cp315-win_amd64.pyd +0 -0
  148. tests/bake_eval_probe.cp315-win_amd64.pyd +0 -0
@@ -0,0 +1,22 @@
1
+ from .c_abc cimport LogicGroup
2
+
3
+
4
+ cdef class LogicMapping(LogicGroup):
5
+ cdef dict __dict__
6
+ cdef readonly dict data
7
+
8
+ cdef object c_get(self, str key)
9
+
10
+
11
+ cdef class LogicSequence(LogicGroup):
12
+ cdef dict __dict__
13
+ cdef readonly list data
14
+
15
+ cdef object c_get(self, ssize_t index)
16
+
17
+
18
+ cdef class LogicGenerator(LogicGroup):
19
+ cdef dict __dict__
20
+ cdef readonly object data
21
+
22
+ cdef object c_next(self)
@@ -0,0 +1,245 @@
1
+ from collections.abc import Iterator, Sequence, Generator
2
+ from typing import Any, Optional
3
+
4
+ from .c_abc import LogicGroup
5
+ from .c_node import GetterExpression, AttrExpression
6
+
7
+
8
+ class LogicMapping(LogicGroup):
9
+ """A mapping-like logic group that decouples stored data from the
10
+ runtime context of a logic group.
11
+
12
+ Instances behave like a read/write mapping container at the Python
13
+ level; expressions created against a `LogicMapping` instance will
14
+ consult the mapping stored in the group's contexts.
15
+
16
+ Attributes:
17
+ data: The underlying dict object used to store key/value pairs.
18
+ """
19
+
20
+ data: dict[str, Any]
21
+
22
+ def __init__(self, *, name: str = None, data: dict[str, Any] = None, parent: Any | None = None, contexts: Optional[dict] = None) -> None:
23
+ """Initialize the LogicMapping.
24
+
25
+ Arguments:
26
+ name: Logical name for this group.
27
+ data: Optional initial dict to use. If not a dict, it will be converted to a dict. If ``None``, the dict
28
+ will be taken from or created inside the group's ``contexts``
29
+ under the key ``'data'``.
30
+ parent: Optional parent logic group (kept for parity with runtime
31
+ behaviour; type is intentionally elided here).
32
+ contexts: Optional dict to use for the group's contexts. When not
33
+ provided, a default contexts mapping will be used/created by
34
+ the runtime manager.
35
+ """
36
+
37
+ def __bool__(self) -> bool:
38
+ """Return True when the underlying mapping is non-empty.
39
+
40
+ Returns:
41
+ True if the mapping contains at least one key; False otherwise.
42
+ """
43
+
44
+ def __len__(self) -> int:
45
+ """Return the number of items stored in the mapping.
46
+
47
+ Returns:
48
+ The number of key/value pairs in the underlying mapping.
49
+ """
50
+
51
+ def __getitem__(self, key: str) -> AttrExpression:
52
+ """Return an expression representing the named key in this mapping.
53
+
54
+ The return value is an expression object (implementation-specific)
55
+ that, when evaluated, will fetch the value stored under ``key``.
56
+
57
+ Args:
58
+ key: The mapping key.
59
+
60
+ Returns:
61
+ An AttrExpression that references ``key`` inside this mapping.
62
+ """
63
+
64
+ def __getattr__(self, key: str) -> AttrExpression:
65
+ """Alias for ``__getitem__`` that allows attribute-style access.
66
+
67
+ Args:
68
+ key: The attribute name to access.
69
+
70
+ Returns:
71
+ An AttrExpression that references ``key`` inside this mapping.
72
+ """
73
+
74
+ def __contains__(self, key: str) -> bool:
75
+ """Return True if ``key`` exists in the mapping."""
76
+
77
+ def update(self, *args: Any, **kwargs: Any) -> None:
78
+ """Update the underlying mapping with the provided items.
79
+
80
+ Accepts the same arguments as :meth:`dict.update`.
81
+ """
82
+
83
+ def clear(self) -> None:
84
+ """Remove all items from the underlying mapping."""
85
+
86
+
87
+ class LogicSequence(LogicGroup):
88
+ """A sequence-like logic group that exposes an ordered collection to
89
+ logic expressions.
90
+
91
+ This class mimics the behaviour of Python sequences at the API layer
92
+ so that expressions can index into it (e.g. ``seq[0]``) and tools can
93
+ iterate over it to produce expression entries.
94
+
95
+ Attributes:
96
+ data: The underlying list object used to store items.
97
+ """
98
+
99
+ data: list[Any]
100
+
101
+ def __init__(self, *, name: str = None, data: list[Any] = None, parent: Any | None = None, contexts: Optional[dict] = None) -> None:
102
+ """Initialize the LogicSequence.
103
+
104
+ Args:
105
+ name: Logical name for this group.
106
+ data: Optional initial list to use. If not a list, it will be converted to a list. If ``None``, the list
107
+ will be taken from or created inside the group's ``contexts``
108
+ under the key ``'data'``.
109
+ parent: Optional parent logic group (opaque in this stub).
110
+ contexts: Optional contexts mapping used by the runtime manager.
111
+ """
112
+
113
+ def __iter__(self) -> Iterator[GetterExpression]:
114
+ """Yields GetterExpression objects representing each element in the sequence.
115
+
116
+ Yields:
117
+ GetterExpression objects (index-based) that can evaluate to the
118
+ underlying sequence items.
119
+ """
120
+
121
+ def __len__(self) -> int:
122
+ """Return the length of the underlying sequence."""
123
+
124
+ def __getitem__(self, index: int) -> GetterExpression:
125
+ """Return an expression referencing the element at ``index``.
126
+
127
+ Negative indices follow Python semantics if the underlying
128
+ sequence supports them.
129
+
130
+ Args:
131
+ index: The index to access.
132
+
133
+ Returns:
134
+ A GetterExpression that, when evaluated, returns the item at
135
+ the requested index.
136
+ """
137
+
138
+ def __contains__(self, item: Any) -> bool:
139
+ """Return True if ``item`` is present in the underlying sequence."""
140
+
141
+ def append(self, value: Any) -> None:
142
+ """Append ``value`` to the underlying sequence."""
143
+
144
+ def extend(self, iterable: Sequence[Any]) -> None:
145
+ """Extend the underlying sequence by the items from ``iterable``."""
146
+
147
+ def insert(self, index: int, value: Any) -> None:
148
+ """Insert ``value`` at position ``index`` in the underlying sequence."""
149
+
150
+ def remove(self, value: Any) -> None:
151
+ """Remove the first occurrence of ``value`` from the underlying sequence."""
152
+
153
+ def pop(self, index: int = -1) -> Any:
154
+ """Remove and return item at ``index`` (default last).
155
+
156
+ Args:
157
+ index: Position of item to pop; default -1 (last item).
158
+
159
+ Returns:
160
+ The removed item.
161
+ """
162
+
163
+ def clear(self) -> None:
164
+ """Remove all items from the underlying sequence."""
165
+
166
+ def __bool__(self) -> bool:
167
+ """Return True when the underlying sequence is non-empty."""
168
+
169
+
170
+ class LogicGenerator:
171
+ """Wraps a generator/iterator to expose generator protocol operations
172
+ via a logic-group object.
173
+
174
+ This object is a thin wrapper around a Python iterator/generator.
175
+ It exposes the standard generator protocol methods so callers can use
176
+ ``next()``, ``send()``, ``throw()``, and ``close()`` directly on the
177
+ logic generator instance.
178
+
179
+ Attributes:
180
+ data: The underlying generator/iterator object.
181
+ """
182
+
183
+ data: Generator
184
+
185
+ def __init__(self, *, name: str = None, data: Generator = None, parent: Any | None = None, contexts: Optional[dict] = None) -> None:
186
+ """Initialize the LogicGenerator.
187
+
188
+ Args:
189
+ name: Logical name for this group.
190
+ data: Optional generator/iterator object. If ``None``, the implementation
191
+ may attempt to retrieve a generator from the group's
192
+ ``contexts`` mapping (behavior depends on the runtime).
193
+ """
194
+
195
+ def __iter__(self) -> LogicGenerator:
196
+ """Return self to support iteration protocol.
197
+
198
+ Returns:
199
+ The generator wrapper itself; calling ``iter()`` on the
200
+ instance returns the same object so ``for x in instance:``
201
+ works as expected.
202
+ """
203
+
204
+ def __next__(self) -> Any:
205
+ """Return the next value from the wrapped generator.
206
+
207
+ Raises:
208
+ StopIteration: When the wrapped generator is exhausted.
209
+ """
210
+
211
+ def send(self, value: Any) -> Any:
212
+ """Send a value into the wrapped generator.
213
+
214
+ Delegates to the underlying generator's :meth:`send` method. The
215
+ original exceptions from the wrapped generator (such as
216
+ :class:`AttributeError` when the underlying iterator does not
217
+ implement ``send``) are allowed to propagate.
218
+
219
+ Args:
220
+ value: The value to send into the generator.
221
+
222
+ Returns:
223
+ The next yielded value from the generator.
224
+ """
225
+
226
+ def throw(self, typ: type[BaseException], val: Optional[BaseException] = None, tb: Optional[Any] = None) -> Any:
227
+ """Raise an exception inside the wrapped generator.
228
+
229
+ Delegates directly to the wrapped generator's :meth:`throw`.
230
+
231
+ Args:
232
+ typ: Exception class to raise inside the generator.
233
+ val: Optional exception instance or value.
234
+ tb: Optional traceback object.
235
+
236
+ Returns:
237
+ The next yielded value from the generator (if any).
238
+ """
239
+
240
+ def close(self) -> None:
241
+ """Close the wrapped generator by delegating to its :meth:`close`.
242
+
243
+ Any exceptions raised by the generator's close method are
244
+ propagated unchanged.
245
+ """
@@ -0,0 +1,138 @@
1
+ from collections.abc import Mapping, Sequence, Generator
2
+
3
+ from cpython.dict cimport PyDict_GetItem
4
+ from cpython.object cimport PyObject
5
+ from cpython.ref cimport Py_INCREF
6
+
7
+ from .c_abc cimport LogicGroup
8
+ from .c_node cimport AttrExpression, GetterExpression
9
+
10
+ from . import LOGGER
11
+
12
+
13
+ cdef class LogicMapping(LogicGroup):
14
+ def __cinit__(self, *, str name=None, object data=None, LogicGroup parent=None, dict contexts=None, **kwargs):
15
+ cdef object ctx_data
16
+ if data is None:
17
+ ctx_data = self.contexts.setdefault('data', {})
18
+ if isinstance(ctx_data, dict):
19
+ self.data = <dict> ctx_data
20
+ elif isinstance(ctx_data, Mapping):
21
+ LOGGER.info(f'Using non-dict mapping for {self} data, unlinking and converting to dict...')
22
+ self.data = dict(ctx_data)
23
+ else:
24
+ raise TypeError("The 'data' parameter must be a Mapping!.")
25
+ else:
26
+ self.data = <dict> data
27
+
28
+ cdef object c_get(self, str key):
29
+ cdef PyObject* v = PyDict_GetItem(self.data, key)
30
+ if v:
31
+ Py_INCREF(<object> v)
32
+ return <object> v
33
+ raise KeyError(key)
34
+
35
+ def __bool__(self):
36
+ return bool(self.data)
37
+
38
+ def __len__(self):
39
+ return self.data.__len__()
40
+
41
+ def __getitem__(self, str key):
42
+ return AttrExpression(attr=key, logic_group=self)
43
+
44
+ def __getattr__(self, str key):
45
+ return AttrExpression(attr=key, logic_group=self)
46
+
47
+ def __contains__(self, str key):
48
+ return key in self.data
49
+
50
+ def update(self, *args, **kwargs):
51
+ self.data.update(*args, **kwargs)
52
+
53
+ def clear(self):
54
+ self.data.clear()
55
+
56
+
57
+ cdef class LogicSequence(LogicGroup):
58
+ def __cinit__(self, *, str name=None, object data=None, LogicGroup parent=None, dict contexts=None, **kwargs):
59
+ cdef object ctx_data
60
+ if data is None:
61
+ ctx_data = self.contexts.setdefault('data', [])
62
+ if isinstance(ctx_data, list):
63
+ self.data = <list> ctx_data
64
+ elif isinstance(ctx_data, Sequence):
65
+ LOGGER.info(f'Using non-list sequence for {self} data, converting to list...')
66
+ self.data = list(ctx_data)
67
+ else:
68
+ raise TypeError("The 'data' parameter must be a Sequence!.")
69
+ else:
70
+ self.data = <list> data
71
+
72
+ cdef object c_get(self, ssize_t index):
73
+ return self.data[index]
74
+
75
+ # === Python interface conveniences ===
76
+
77
+ def __iter__(self):
78
+ for index, _ in enumerate(self.data):
79
+ yield GetterExpression(key=index, logic_group=self)
80
+
81
+ def __len__(self):
82
+ return len(self.data)
83
+
84
+ def __getitem__(self, index):
85
+ return GetterExpression(key=index, logic_group=self)
86
+
87
+ def __contains__(self, item):
88
+ return item in self.data
89
+
90
+ def append(self, value):
91
+ self.data.append(value)
92
+
93
+ def extend(self, iterable):
94
+ self.data.extend(iterable)
95
+
96
+ def insert(self, index, value):
97
+ self.data.insert(index, value)
98
+
99
+ def remove(self, value):
100
+ self.data.remove(value)
101
+
102
+ def pop(self, index=-1):
103
+ return self.data.pop(index)
104
+
105
+ def clear(self):
106
+ self.data.clear()
107
+
108
+ def __bool__(self):
109
+ return bool(self.data)
110
+
111
+
112
+ cdef class LogicGenerator(LogicGroup):
113
+ def __cinit__(self, *, str name=None, object data=None, LogicGroup parent=None, dict contexts=None, **kwargs):
114
+ if data is None:
115
+ data = self.contexts.setdefault('data')
116
+
117
+ if isinstance(data, Generator):
118
+ self.data = data
119
+ raise TypeError("The 'data' parameter must be a Generator!.")
120
+
121
+ cdef object c_next(self):
122
+ return next(self.data)
123
+
124
+ # === Python generator protocol & control methods (added) ===
125
+ def __iter__(self):
126
+ return self
127
+
128
+ def __next__(self):
129
+ return self.c_next()
130
+
131
+ def send(self, value):
132
+ return self.data.send(value)
133
+
134
+ def throw(self, typ, val=None, tb=None):
135
+ return self.data.throw(typ, val, tb)
136
+
137
+ def close(self):
138
+ return self.data.close()
@@ -0,0 +1,95 @@
1
+ from libc.stdint cimport uint8_t
2
+
3
+ from .c_abc cimport LogicNode, LogicGroup, BreakpointNode
4
+
5
+
6
+ cdef class NodeEvalPath(list):
7
+ pass
8
+
9
+
10
+ cdef class RootLogicNode(LogicNode):
11
+ cdef readonly bint inherit_contexts
12
+ cdef readonly list _eval_path
13
+
14
+ cpdef BreakpointNode get_breakpoint(self)
15
+
16
+
17
+ cdef class ContextLogicExpression(LogicNode):
18
+ cdef readonly LogicGroup logic_group
19
+
20
+ @staticmethod
21
+ cdef inline object c_safe_eval(object v)
22
+
23
+ @staticmethod
24
+ cdef inline str c_safe_alias(object v)
25
+
26
+
27
+ cdef class AttrExpression(ContextLogicExpression):
28
+ cdef readonly str attr
29
+
30
+
31
+ cdef class AttrNestedExpression(ContextLogicExpression):
32
+ cdef readonly list attrs
33
+
34
+
35
+ cdef class GetterExpression(ContextLogicExpression):
36
+ cdef readonly object key
37
+
38
+
39
+ cdef class GetterNestedExpression(ContextLogicExpression):
40
+ cdef readonly list keys
41
+
42
+
43
+ cdef class MathExpressionOperator:
44
+ cdef readonly str name
45
+ cdef readonly str value
46
+ cdef readonly str op
47
+
48
+
49
+ cdef class MathExpression(ContextLogicExpression):
50
+ cdef readonly str op_name
51
+ cdef readonly str op_repr
52
+ cdef readonly object op_func
53
+ cdef readonly object left
54
+ cdef readonly object right
55
+
56
+ cdef str c_op_style_repr(self)
57
+ cdef str c_func_style_repr(self)
58
+
59
+
60
+ cdef class ComparisonExpressionOperator:
61
+ cdef readonly str name
62
+ cdef readonly str value
63
+ cdef readonly str op
64
+ cdef uint8_t int_enum
65
+
66
+
67
+ cdef class ComparisonExpression(ContextLogicExpression):
68
+ cdef readonly str op_name
69
+ cdef readonly str op_repr
70
+ cdef readonly object op_func
71
+ cdef readonly object left
72
+ cdef readonly object right
73
+ cdef uint8_t op_enum
74
+
75
+ cdef str c_op_style_repr(self)
76
+ cdef str c_func_style_repr(self)
77
+
78
+
79
+ cdef class LogicalExpressionOperator:
80
+ cdef readonly str name
81
+ cdef readonly str value
82
+ cdef readonly str op
83
+ cdef uint8_t int_enum
84
+
85
+
86
+ cdef class LogicalExpression(ContextLogicExpression):
87
+ cdef readonly str op_name
88
+ cdef readonly str op_repr
89
+ cdef readonly object op_func
90
+ cdef readonly object left
91
+ cdef readonly object right
92
+ cdef uint8_t op_enum
93
+
94
+ cdef str c_op_style_repr(self)
95
+ cdef str c_func_style_repr(self)