fix(vision): NaN/inf/bool di uno strumento non diventano più una quota (#16)

runner.run_graph esclude bool e NaN/inf dagli output numerici, con il
motivo in RunOutcome.invalid_outputs. vision_service tratta una quota
mappata con valore None/assente/non finito come "non prodotta" (422),
invece di arrivare a float(None) e sollevare TypeError.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 22:35:53 +02:00
parent 10261b66f0
commit 20957e517d
5 changed files with 137 additions and 4 deletions
+47
View File
@@ -72,6 +72,53 @@ def test_a_broken_tool_does_not_sink_the_others():
assert any(key.endswith(".diameter") for key in outcome.outputs)
class _FakeResult:
"""Stands in for a vs-task tool result: only what run_graph touches."""
def __init__(self, tool_id, tool_name, ok, outputs=None, error=None):
self.tool_id = tool_id
self.tool_name = tool_name
self.ok = ok
self.outputs = outputs or {}
self.error = error
def test_a_nan_output_is_dropped_not_measured(monkeypatch):
"""vs-measure emits NaN on an empty slice (caliper.py:112 per the
revisione) - a NaN must not become a quote's value (#16)."""
def fake_run(self, context=None):
return [_FakeResult("t1", "diametro", True, outputs={"diameter": float("nan")})]
monkeypatch.setattr(runner.Task, "run", fake_run)
outcome = run_graph(a_disc(), a_circle_graph())
assert outcome.outputs == {}
assert outcome.invalid_outputs == {"t1.diameter": "nan"}
def test_an_infinite_output_is_dropped_not_measured(monkeypatch):
def fake_run(self, context=None):
return [_FakeResult("t1", "diametro", True, outputs={"diameter": float("inf")})]
monkeypatch.setattr(runner.Task, "run", fake_run)
outcome = run_graph(a_disc(), a_circle_graph())
assert outcome.outputs == {}
assert outcome.invalid_outputs == {"t1.diameter": "infinite"}
def test_a_bool_output_is_not_treated_as_a_measurable_number(monkeypatch):
"""bool is a subclass of int - a flag output must not become a quote."""
def fake_run(self, context=None):
return [_FakeResult("t1", "flag", True, outputs={"present": True})]
monkeypatch.setattr(runner.Task, "run", fake_run)
outcome = run_graph(a_disc(), a_circle_graph())
assert outcome.outputs == {}
assert outcome.invalid_outputs == {}
def test_the_engine_says_which_version_it_is():
version = engine_version()
assert len(version) == 40 # a full git SHA