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,277 @@
1
+ from cpython.unicode cimport PyUnicode_AsUTF8, PyUnicode_FromString
2
+ from libc.stdint cimport uintptr_t
3
+
4
+ from .c_allocator_protocol cimport DCG_DEFAULT_ALLOCATOR
5
+ from .c_edge cimport NO_CONDITION
6
+ from .c_node cimport NODE_REGISTRY
7
+ from .c_var cimport c_dcg_ret_code_name, c_dcg_var_pyunpack
8
+
9
+
10
+ cdef class RootLogicNode(LogicNode):
11
+ def __init__(self, *, str name='Entry Point', bint inherit_contexts=False, **kwargs):
12
+ cdef dcg_root_node* node = c_dcg_node_new_root(PyUnicode_AsUTF8(name), DCG_DEFAULT_ALLOCATOR)
13
+ if not node:
14
+ raise MemoryError('Failed to allocate the RootLogicNode.')
15
+
16
+ self.header = &node.base
17
+ self.owner = True
18
+ self.name = name
19
+ node.inherit_contexts = inherit_contexts
20
+ # The record is the root's own field, so the view is taken once, over it:
21
+ # what it reads is whatever the last walk left there.
22
+ self.eval_path = NodeEvalPathView.c_from_header(&node.eval_path)
23
+ self.c_register_node()
24
+
25
+ # === Eval Protocol ===
26
+
27
+ cdef void c_eval(self):
28
+ if not self.header:
29
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
30
+
31
+ cdef dcg_root_node* root = <dcg_root_node*> self.header
32
+ cdef int ret_code = c_dcg_root_node_eval(root)
33
+ self.c_check_eval_code(ret_code, root.eval_path.failed)
34
+
35
+ def eval(self):
36
+ self.c_eval()
37
+
38
+ cdef dcg_root_node* root = <dcg_root_node*> self.header
39
+ cdef dcg_node* leaf = root.eval_path.leaf
40
+ if not leaf:
41
+ raise RuntimeError(f'{self.__class__.__name__} reached no leaf and reported no error.')
42
+
43
+ return c_dcg_var_pyunpack(&leaf.out)
44
+
45
+ def __call__(self):
46
+ return self.eval()
47
+
48
+ # === Web UI ===
49
+
50
+ def to_html(self, str file_name=None, bint with_eval=True):
51
+ from ...webui.bake import to_html
52
+ to_html(self, file_name or f'{self.repr}.html', with_eval)
53
+
54
+ def show(self, **kwargs):
55
+ from ...webui.bake import show
56
+ show(self, **kwargs)
57
+
58
+ def watch(self, **kwargs):
59
+ from ...webui.bake import watch
60
+ watch(self, **kwargs)
61
+
62
+ # === Bake Protocol ===
63
+
64
+ cpdef object bake(self, bint validate_only=False):
65
+ # The protocol lives in a module above this one - the bake pass is asked
66
+ # of a root and reads every family to answer - so the reach is the
67
+ # module's Python door at call time, never a cimport (DEPENDENCY.md 4.3).
68
+ from .c_bake import c_dcg_bake_root
69
+ return c_dcg_bake_root(self, validate_only)
70
+
71
+ def get_breakpoint(self):
72
+ """The breakpoint this graph left waiting, or None if it left none.
73
+
74
+ A breakpoint that has not resumed into anything yet is where a branch
75
+ stopped, and that is what this looks for - the place a build can take up
76
+ again. What makes a graph assemblable from several places is exactly
77
+ this: one function builds up to a break, this hands the break back, and
78
+ the next function takes it and builds the rest, so the two halves never
79
+ have to be in the same scope, or even the same function.
80
+
81
+ The search itself is the C layer's - ``c_dcg_node_get_breakpoint`` walks
82
+ the graph's own links. Nothing here needs the Python side to have kept a
83
+ wrapper for every node the walk crosses, which is what makes it work on a
84
+ graph the build only partly came through Python.
85
+
86
+ Returns:
87
+ The waiting breakpoint, or None when the graph has none.
88
+ """
89
+ if not self.header:
90
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
91
+
92
+ cdef dcg_breakpoint_node* found = c_dcg_node_get_breakpoint(self.header)
93
+ if not found:
94
+ return None
95
+ return NODE_REGISTRY[<uintptr_t> &found.base]
96
+
97
+ property inherit_contexts:
98
+ def __get__(self):
99
+ if not self.header:
100
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
101
+ return bool((<dcg_root_node*> self.header).inherit_contexts)
102
+
103
+
104
+ cdef class NodeEvalPathView:
105
+ def __init__(self, RootLogicNode node):
106
+ self.header = <const dcg_node_eval_path*> &(<dcg_root_node*> node.header).eval_path
107
+
108
+ @staticmethod
109
+ cdef inline NodeEvalPathView c_from_header(const dcg_node_eval_path* path):
110
+ cdef NodeEvalPathView view = NodeEvalPathView.__new__(NodeEvalPathView)
111
+ view.header = path
112
+ return view
113
+
114
+ def __repr__(self):
115
+ if not self.header:
116
+ return f'<{self.__class__.__name__} (Uninitialized)>'
117
+ cdef dcg_node_eval_path* path = <dcg_node_eval_path*> self.header
118
+ return f'<{self.__class__.__name__}(nodes={path.n_nodes}, code={self.code_name}, leaf={self.leaf})>'
119
+
120
+ def __len__(self):
121
+ if not self.header:
122
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
123
+ return (<dcg_node_eval_path*> self.header).n_nodes
124
+
125
+ def __iter__(self):
126
+ if not self.header:
127
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
128
+ cdef dcg_node_eval_path* path = <dcg_node_eval_path*> self.header
129
+ cdef size_t index
130
+ for index in range(path.n_nodes):
131
+ yield NODE_REGISTRY[<uintptr_t> path.node[index]]
132
+
133
+ def __getitem__(self, Py_ssize_t index):
134
+ cdef Py_ssize_t count = len(self)
135
+ if index < 0:
136
+ index += count
137
+ if index < 0 or index >= count:
138
+ raise IndexError(f'{self.__class__.__name__} index out of range')
139
+ return NODE_REGISTRY[<uintptr_t> (<dcg_node_eval_path*> self.header).node[index]]
140
+
141
+ # === Python Properties ===
142
+
143
+ property address:
144
+ def __get__(self):
145
+ if not self.header:
146
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
147
+ return <uintptr_t> self.header
148
+
149
+ property nodes:
150
+ def __get__(self):
151
+ if not self.header:
152
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
153
+ return list(self)
154
+
155
+ property capacity:
156
+ def __get__(self):
157
+ if not self.header:
158
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
159
+ return (<dcg_node_eval_path*> self.header).capacity
160
+
161
+ property code:
162
+ def __get__(self):
163
+ if not self.header:
164
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
165
+ return <int> (<dcg_node_eval_path*> self.header).code
166
+
167
+ property code_name:
168
+ def __get__(self):
169
+ if not self.header:
170
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
171
+ return PyUnicode_FromString(c_dcg_ret_code_name((<dcg_node_eval_path*> self.header).code))
172
+
173
+ property leaf:
174
+ def __get__(self):
175
+ if not self.header:
176
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
177
+ cdef dcg_node* leaf = (<dcg_node_eval_path*> self.header).leaf
178
+ return None if not leaf else NODE_REGISTRY[<uintptr_t> leaf]
179
+
180
+ property failed:
181
+ def __get__(self):
182
+ if not self.header:
183
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
184
+ cdef dcg_node* failed = (<dcg_node_eval_path*> self.header).failed
185
+ return None if not failed else NODE_REGISTRY[<uintptr_t> failed]
186
+
187
+ property seq_id:
188
+ def __get__(self):
189
+ if not self.header:
190
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
191
+ return (<dcg_node_eval_path*> self.header).seq_id
192
+
193
+
194
+ cdef class BreakpointNode(LogicNode):
195
+ def __init__(self, *, object break_from=None, str repr=None, bint autogen=True, **kwargs):
196
+ cdef dcg_logic_group* group = NULL
197
+ cdef dcg_breakpoint_node* node
198
+ if break_from:
199
+ group = <dcg_logic_group*> <uintptr_t> break_from.address
200
+ node = c_dcg_node_new_breakpoint(
201
+ group,
202
+ PyUnicode_AsUTF8(repr) if repr else NULL,
203
+ DCG_DEFAULT_ALLOCATOR,
204
+ )
205
+ if not node:
206
+ raise MemoryError('Failed to allocate the BreakpointNode.')
207
+
208
+ self.header = &node.base
209
+ self.owner = True
210
+ self.break_from = break_from
211
+ self.c_register_node()
212
+
213
+ # === Python Interfaces ===
214
+
215
+ @classmethod
216
+ def break_(cls, object break_from, **kwargs):
217
+ """Break out of a group, and hand back the breakpoint that did it.
218
+
219
+ A break is a node: it takes the arm the build was about to fill, and the
220
+ build continues from IT rather than from the group it left. That is what
221
+ makes this the door for assembling a graph in pieces - one function
222
+ builds up to the break and returns, and the break it made is entered here
223
+ to carry on outside the group.
224
+
225
+ The breakpoint is built first and then installed, rather than made by the
226
+ install: the block that lands in the graph has to be the one this wrapper
227
+ holds, or the caller would be handed a handle on a node that is not in
228
+ the graph.
229
+
230
+ Args:
231
+ break_from: The group being broken out of.
232
+ **kwargs: Passed to the constructor.
233
+
234
+ Returns:
235
+ The breakpoint, now in the graph and waiting to resume into the next
236
+ node entered.
237
+
238
+ Raises:
239
+ RuntimeError: When the C layer cannot place it.
240
+ MemoryError: When the block cannot be allocated.
241
+ """
242
+ cdef BreakpointNode breakpoint = cls(break_from=break_from, **kwargs)
243
+
244
+ cdef int ret_code = c_dcg_lgm_install_breakpoint(
245
+ LogicNode.c_get_manager(),
246
+ <dcg_breakpoint_node*> breakpoint.header,
247
+ )
248
+ if ret_code != dcg_ret_code.DCG_OK:
249
+ raise RuntimeError(f'c_dcg_lgm_install_breakpoint failed with err code: {ret_code}')
250
+ return breakpoint
251
+
252
+ def connect(self, LogicNode child):
253
+ """Connect a node as what this breakpoint resumes into.
254
+
255
+ A breakpoint resumes into exactly one node, which is what its arm is for,
256
+ so a second connection is refused by the C layer rather than replacing
257
+ the first - see ``append``.
258
+ """
259
+ self.append(child, NO_CONDITION)
260
+
261
+ # === Python Properties ===
262
+
263
+ property linked_to:
264
+ def __get__(self):
265
+ """The node this breakpoint resumes into, or None while it waits."""
266
+ if not self.header:
267
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
268
+ for child in self.children.values():
269
+ return child
270
+ return None
271
+
272
+ property await_connection:
273
+ def __get__(self):
274
+ if not self.header:
275
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
276
+ cdef dcg_breakpoint_node* node = <dcg_breakpoint_node*> self.header
277
+ return node.await_connection