computation-graph 58__tar.gz → 60__tar.gz

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 (35) hide show
  1. {computation_graph-58 → computation_graph-60}/PKG-INFO +1 -1
  2. {computation_graph-58 → computation_graph-60}/computation_graph/graph_test.py +38 -0
  3. {computation_graph-58 → computation_graph-60}/computation_graph/run.py +48 -51
  4. {computation_graph-58 → computation_graph-60}/computation_graph.egg-info/PKG-INFO +1 -1
  5. {computation_graph-58 → computation_graph-60}/setup.py +1 -1
  6. {computation_graph-58 → computation_graph-60}/LICENSE.md +0 -0
  7. {computation_graph-58 → computation_graph-60}/README.md +0 -0
  8. {computation_graph-58 → computation_graph-60}/computation_graph/__init__.py +0 -0
  9. {computation_graph-58 → computation_graph-60}/computation_graph/base_types.py +0 -0
  10. {computation_graph-58 → computation_graph-60}/computation_graph/composers/__init__.py +0 -0
  11. {computation_graph-58 → computation_graph-60}/computation_graph/composers/composers_test.py +0 -0
  12. {computation_graph-58 → computation_graph-60}/computation_graph/composers/condition.py +0 -0
  13. {computation_graph-58 → computation_graph-60}/computation_graph/composers/condition_test.py +0 -0
  14. {computation_graph-58 → computation_graph-60}/computation_graph/composers/debug.py +0 -0
  15. {computation_graph-58 → computation_graph-60}/computation_graph/composers/duplication.py +0 -0
  16. {computation_graph-58 → computation_graph-60}/computation_graph/composers/lift.py +0 -0
  17. {computation_graph-58 → computation_graph-60}/computation_graph/composers/logic.py +0 -0
  18. {computation_graph-58 → computation_graph-60}/computation_graph/composers/memory.py +0 -0
  19. {computation_graph-58 → computation_graph-60}/computation_graph/composers/memory_test.py +0 -0
  20. {computation_graph-58 → computation_graph-60}/computation_graph/graph.py +0 -0
  21. {computation_graph-58 → computation_graph-60}/computation_graph/graph_runners.py +0 -0
  22. {computation_graph-58 → computation_graph-60}/computation_graph/legacy.py +0 -0
  23. {computation_graph-58 → computation_graph-60}/computation_graph/signature.py +0 -0
  24. {computation_graph-58 → computation_graph-60}/computation_graph/trace/__init__.py +0 -0
  25. {computation_graph-58 → computation_graph-60}/computation_graph/trace/ascii.py +0 -0
  26. {computation_graph-58 → computation_graph-60}/computation_graph/trace/graphviz.py +0 -0
  27. {computation_graph-58 → computation_graph-60}/computation_graph/trace/graphviz_test.py +0 -0
  28. {computation_graph-58 → computation_graph-60}/computation_graph/trace/mermaid.py +0 -0
  29. {computation_graph-58 → computation_graph-60}/computation_graph/trace/trace_utils.py +0 -0
  30. {computation_graph-58 → computation_graph-60}/computation_graph.egg-info/SOURCES.txt +0 -0
  31. {computation_graph-58 → computation_graph-60}/computation_graph.egg-info/dependency_links.txt +0 -0
  32. {computation_graph-58 → computation_graph-60}/computation_graph.egg-info/requires.txt +0 -0
  33. {computation_graph-58 → computation_graph-60}/computation_graph.egg-info/top_level.txt +0 -0
  34. {computation_graph-58 → computation_graph-60}/pyproject.toml +0 -0
  35. {computation_graph-58 → computation_graph-60}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: computation-graph
3
- Version: 58
3
+ Version: 60
4
4
  Requires-Python: >=3
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE.md
@@ -233,6 +233,18 @@ def test_first():
233
233
  )
234
234
 
235
235
 
236
+ async def test_raise_handled_from_async():
237
+ async def raises():
238
+ raise base_types.SkipComputationError
239
+
240
+ assert (
241
+ await graph_runners.nullary_infer_sink(
242
+ composers.make_first(raises, lambda: 1, lambda: 2)
243
+ )
244
+ == 1
245
+ )
246
+
247
+
236
248
  def test_raise_unhandled_exception():
237
249
  class MyExceptionError(Exception):
238
250
  ...
@@ -244,6 +256,32 @@ def test_raise_unhandled_exception():
244
256
  graph_runners.nullary_infer_sink(composers.make_first(raises, lambda: 1))
245
257
 
246
258
 
259
+ async def test_raise_exception_in_sync_after_async():
260
+ def raises(x):
261
+ raise TypeError("BAD")
262
+
263
+ async def async_source():
264
+ return 4
265
+
266
+ with pytest.raises(TypeError, match="BAD"):
267
+ await run.to_callable_strict(
268
+ composers.compose_left(async_source, raises, lambda x: 1)
269
+ )({}, {})
270
+
271
+
272
+ async def test_raise_exception_in_async_after_sync():
273
+ async def raises(x):
274
+ raise TypeError("BAD")
275
+
276
+ def source():
277
+ return 4
278
+
279
+ with pytest.raises(TypeError, match="BAD"):
280
+ await run.to_callable_strict(
281
+ composers.compose_left(source, raises, lambda x: 1)
282
+ )({}, {})
283
+
284
+
247
285
  def test_first_all_unactionable():
248
286
  def raises():
249
287
  raise base_types.SkipComputationError
@@ -102,7 +102,7 @@ def _profile(node, time_started: float):
102
102
  )
103
103
 
104
104
 
105
- _group_by_is_async_result = opt_gamla.groupby(lambda k_v: inspect.isawaitable(k_v[1]))
105
+ _group_by_is_future = opt_gamla.groupby(lambda k_v: asyncio.isfuture(k_v[1]))
106
106
 
107
107
 
108
108
  _is_graph_async = opt_gamla.compose_left(
@@ -210,7 +210,7 @@ def _to_callable_with_side_effect_for_single_and_multiple(
210
210
  edges, handled_exceptions, single_node_side_effect
211
211
  )
212
212
 
213
- topological_layers = opt_gamla.pipe(
213
+ topological_sorted_nodes = opt_gamla.pipe(
214
214
  edges,
215
215
  _toposort_nodes,
216
216
  gamla.remove(gamla.contains(placeholder_to_future_source)),
@@ -226,46 +226,44 @@ def _to_callable_with_side_effect_for_single_and_multiple(
226
226
  if is_async:
227
227
 
228
228
  async def final_runner(sources_to_values):
229
- d = gamla.pipe(
230
- topological_layers,
231
- _run_graph(
232
- translate_source_to_placeholder(sources_to_values),
233
- handled_exceptions,
234
- ),
235
- dict,
229
+ node_to_task_or_result = _run_graph(
230
+ translate_source_to_placeholder(sources_to_values),
231
+ handled_exceptions,
232
+ topological_sorted_nodes,
236
233
  )
237
- results_by_is_async = _group_by_is_async_result(d.items())
234
+ results_by_is_async = _group_by_is_future(node_to_task_or_result.items())
238
235
  async_results = tuple(zip(*results_by_is_async.get(True, ())))
239
236
  sync_results = dict(results_by_is_async.get(False, ()))
240
- return all_node_side_effects_on_edges(
241
- sync_results
242
- | (
243
- {
244
- k: v
245
- for (k, v) in zip(
246
- async_results[0],
247
- await asyncio.gather(
248
- *async_results[1], return_exceptions=True
249
- ),
250
- )
251
- if not isinstance(v, Exception)
252
- }
253
- if async_results
254
- else {}
255
- )
256
- )
237
+
238
+ all_results = sync_results
239
+ if async_results:
240
+ for (node, node_result) in zip(
241
+ async_results[0],
242
+ await asyncio.gather(*async_results[1], return_exceptions=True),
243
+ ):
244
+ e = node_to_task_or_result[node].exception()
245
+ if e and not isinstance(
246
+ e,
247
+ (
248
+ _DepNotFoundError,
249
+ base_types.SkipComputationError,
250
+ *handled_exceptions,
251
+ ),
252
+ ):
253
+ raise e from e
254
+ all_results[node] = node_result
255
+
256
+ return all_node_side_effects_on_edges(all_results)
257
257
 
258
258
  else:
259
259
 
260
260
  def final_runner(sources_to_values):
261
- return gamla.pipe(
262
- topological_layers,
261
+ return all_node_side_effects_on_edges(
263
262
  _run_graph(
264
263
  translate_source_to_placeholder(sources_to_values),
265
264
  handled_exceptions,
266
- ),
267
- dict,
268
- all_node_side_effects_on_edges,
265
+ topological_sorted_nodes,
266
+ )
269
267
  )
270
268
 
271
269
  return (_async_graph_reducer if is_async else _graph_reducer)(final_runner)
@@ -506,25 +504,24 @@ def _make_get_node_executor(
506
504
  return get_executor
507
505
 
508
506
 
509
- def _run_graph(inputs: dict, handled_exceptions):
510
- def run_graph(
511
- nodes: tuple[tuple[base_types.ComputationNode, _NodeExecutor]]
512
- ) -> _NodeToResults:
513
- accumulated_results = inputs.copy()
514
- for node_executor in nodes:
515
- try:
516
- accumulated_results[node_executor[0]] = node_executor[1](
517
- accumulated_results, node_executor[0]
518
- )
519
- except (
520
- _DepNotFoundError,
521
- base_types.SkipComputationError,
522
- *handled_exceptions,
523
- ):
524
- pass
525
- return accumulated_results
526
-
527
- return run_graph
507
+ def _run_graph(
508
+ inputs: dict,
509
+ handled_exceptions,
510
+ topological_sorted_nodes: tuple[tuple[base_types.ComputationNode, _NodeExecutor]],
511
+ ) -> _NodeToResults:
512
+ accumulated_results = inputs.copy()
513
+ for node_executor in topological_sorted_nodes:
514
+ try:
515
+ accumulated_results[node_executor[0]] = node_executor[1](
516
+ accumulated_results, node_executor[0]
517
+ )
518
+ except (
519
+ _DepNotFoundError,
520
+ base_types.SkipComputationError,
521
+ *handled_exceptions,
522
+ ):
523
+ pass
524
+ return accumulated_results
528
525
 
529
526
 
530
527
  def _graph_reducer(graph_callable):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: computation-graph
3
- Version: 58
3
+ Version: 60
4
4
  Requires-Python: >=3
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE.md
@@ -7,7 +7,7 @@ with open("README.md", "r") as fh:
7
7
  setuptools.setup(
8
8
  name="computation-graph",
9
9
  python_requires=">=3",
10
- version="58",
10
+ version="60",
11
11
  long_description=_LONG_DESCRIPTION,
12
12
  long_description_content_type="text/markdown",
13
13
  packages=setuptools.find_namespace_packages(),
File without changes
File without changes