PyDecisionGraph 0.3.2.post1__cp315-cp315t-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.
- decision_graph/__infra__.pxd +1 -0
- decision_graph/__init__.pxd +1 -0
- decision_graph/__init__.py +39 -0
- decision_graph/decision_tree/__init__.pxd +2 -0
- decision_graph/decision_tree/__init__.py +85 -0
- decision_graph/decision_tree/bake/__infra__.pxd +502 -0
- decision_graph/decision_tree/bake/__init__.pxd +502 -0
- decision_graph/decision_tree/bake/__init__.py +29 -0
- decision_graph/decision_tree/bake/c_action.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_action.h +324 -0
- decision_graph/decision_tree/bake/c_action.pxd +54 -0
- decision_graph/decision_tree/bake/c_action.pyi +126 -0
- decision_graph/decision_tree/bake/c_action.pyx +65 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pxd +24 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pyi +61 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pyx +109 -0
- decision_graph/decision_tree/bake/c_bake.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_bake.h +629 -0
- decision_graph/decision_tree/bake/c_bake.pxd +52 -0
- decision_graph/decision_tree/bake/c_bake.pyi +151 -0
- decision_graph/decision_tree/bake/c_bake.pyx +142 -0
- decision_graph/decision_tree/bake/c_collections.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_collections.h +692 -0
- decision_graph/decision_tree/bake/c_collections.pxd +52 -0
- decision_graph/decision_tree/bake/c_collections.pyi +193 -0
- decision_graph/decision_tree/bake/c_collections.pyx +161 -0
- decision_graph/decision_tree/bake/c_const.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_const.h +395 -0
- decision_graph/decision_tree/bake/c_const.pxd +56 -0
- decision_graph/decision_tree/bake/c_const.pyi +305 -0
- decision_graph/decision_tree/bake/c_const.pyx +278 -0
- decision_graph/decision_tree/bake/c_edge.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_edge.h +511 -0
- decision_graph/decision_tree/bake/c_edge.pxd +117 -0
- decision_graph/decision_tree/bake/c_edge.pyi +192 -0
- decision_graph/decision_tree/bake/c_edge.pyx +270 -0
- decision_graph/decision_tree/bake/c_eval.h +848 -0
- decision_graph/decision_tree/bake/c_eval.pxd +40 -0
- decision_graph/decision_tree/bake/c_expr.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_expr.h +1900 -0
- decision_graph/decision_tree/bake/c_expr.pxd +129 -0
- decision_graph/decision_tree/bake/c_expr.pyi +280 -0
- decision_graph/decision_tree/bake/c_expr.pyx +272 -0
- decision_graph/decision_tree/bake/c_hierarchy.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
- decision_graph/decision_tree/bake/c_hierarchy.pxd +71 -0
- decision_graph/decision_tree/bake/c_hierarchy.pyi +409 -0
- decision_graph/decision_tree/bake/c_hierarchy.pyx +277 -0
- decision_graph/decision_tree/bake/c_logic_group.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
- decision_graph/decision_tree/bake/c_logic_group.pxd +162 -0
- decision_graph/decision_tree/bake/c_logic_group.pyi +264 -0
- decision_graph/decision_tree/bake/c_logic_group.pyx +308 -0
- decision_graph/decision_tree/bake/c_node.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_node.h +2660 -0
- decision_graph/decision_tree/bake/c_node.pxd +381 -0
- decision_graph/decision_tree/bake/c_node.pyi +438 -0
- decision_graph/decision_tree/bake/c_node.pyx +639 -0
- decision_graph/decision_tree/bake/c_reconstruct.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_reconstruct.pxd +63 -0
- decision_graph/decision_tree/bake/c_reconstruct.pyi +60 -0
- decision_graph/decision_tree/bake/c_reconstruct.pyx +252 -0
- decision_graph/decision_tree/bake/c_var.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_var.h +2054 -0
- decision_graph/decision_tree/bake/c_var.pxd +205 -0
- decision_graph/decision_tree/bake/c_var.pyi +271 -0
- decision_graph/decision_tree/bake/c_var.pyx +228 -0
- decision_graph/decision_tree/capi/__infra__.pxd +33 -0
- decision_graph/decision_tree/capi/__init__.pxd +33 -0
- decision_graph/decision_tree/capi/__init__.py +57 -0
- decision_graph/decision_tree/capi/c_abc.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_abc.pxd +246 -0
- decision_graph/decision_tree/capi/c_abc.pyi +770 -0
- decision_graph/decision_tree/capi/c_abc.pyx +1532 -0
- decision_graph/decision_tree/capi/c_collection.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_collection.pxd +22 -0
- decision_graph/decision_tree/capi/c_collection.pyi +245 -0
- decision_graph/decision_tree/capi/c_collection.pyx +138 -0
- decision_graph/decision_tree/capi/c_node.cp315t-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_node.pxd +95 -0
- decision_graph/decision_tree/capi/c_node.pyi +492 -0
- decision_graph/decision_tree/capi/c_node.pyx +551 -0
- decision_graph/decision_tree/exc.py +189 -0
- decision_graph/decision_tree/native/__init__.py +57 -0
- decision_graph/decision_tree/native/abc.py +1167 -0
- decision_graph/decision_tree/native/collection.py +134 -0
- decision_graph/decision_tree/native/node.py +521 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_action.c +16320 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_action.h +324 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_allocator_protocol.c +12473 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_bake.c +16485 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_bake.h +629 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_collections.c +17381 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_collections.h +692 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_const.c +20815 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_const.h +395 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_edge.c +20696 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_edge.h +511 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_eval.h +848 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_expr.c +22065 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_expr.h +1900 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.c +23267 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.c +22434 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_node.c +28385 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_node.h +2660 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_reconstruct.c +15955 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_var.c +16881 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_var.h +2054 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_abc.c +59196 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_collection.c +19967 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_node.c +39229 -0
- decision_graph/logic_group/__init__.py +25 -0
- decision_graph/logic_group/base.py +100 -0
- decision_graph/logic_group/pending_request.py +384 -0
- decision_graph/webui/__init__.py +24 -0
- decision_graph/webui/bake/__init__.py +65 -0
- decision_graph/webui/bake/app.py +488 -0
- decision_graph/webui/bake/static/d3.v7.min.js +2 -0
- decision_graph/webui/bake/static/script.js +1440 -0
- decision_graph/webui/bake/static/style.css +920 -0
- decision_graph/webui/bake/templates/index.html +183 -0
- decision_graph/webui/bake/templates/offline.html +184 -0
- decision_graph/webui/capi/__init__.py +54 -0
- decision_graph/webui/capi/app.py +366 -0
- decision_graph/webui/capi/main.py +53 -0
- decision_graph/webui/capi/static/d3.v7.min.js +2 -0
- decision_graph/webui/capi/static/script.js +1026 -0
- decision_graph/webui/capi/static/style.css +656 -0
- decision_graph/webui/capi/templates/index.html +93 -0
- decision_graph/webui/capi/templates/offline.html +94 -0
- decision_graph/webui/native/__init__.py +54 -0
- decision_graph/webui/native/app.py +366 -0
- decision_graph/webui/native/main.py +53 -0
- decision_graph/webui/native/static/d3.v7.min.js +2 -0
- decision_graph/webui/native/static/script.js +1026 -0
- decision_graph/webui/native/static/style.css +656 -0
- decision_graph/webui/native/templates/index.html +93 -0
- decision_graph/webui/native/templates/offline.html +94 -0
- pydecisiongraph-0.3.2.post1.dist-info/METADATA +136 -0
- pydecisiongraph-0.3.2.post1.dist-info/RECORD +148 -0
- pydecisiongraph-0.3.2.post1.dist-info/WHEEL +5 -0
- pydecisiongraph-0.3.2.post1.dist-info/licenses/LICENSE +373 -0
- pydecisiongraph-0.3.2.post1.dist-info/top_level.txt +2 -0
- tests/bake_c_evaluator.cp315t-win_amd64.pyd +0 -0
- tests/bake_eval_probe.cp315t-win_amd64.pyd +0 -0
|
Binary file
|
|
@@ -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()
|
|
Binary file
|
|
@@ -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)
|