Skip to content

Serialize non-primitive strategy parameters defensively - #101

Merged
tim-nish merged 1 commit into
mainfrom
fix/issue-99-strategy-parameter-serialization
Jul 9, 2026
Merged

tim-nish merged 1 commit into
mainfrom
fix/issue-99-strategy-parameter-serialization

Conversation

@tim-nish

@tim-nish tim-nish commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #99.

_strategy_parameters() in benchmark/runner/_run_benchmark.py assumed every non-primitive strategy field could be converted with float(), so a PolicyStrategy holding a neural-network model (PyTorch/Flax/etc.) as a field crashed run_benchmark() at result-serialization time — after the benchmark had already run.

Following the fix suggested in the issue, a new _serialize_parameter() helper serializes defensively:

  • primitives (bool/int/float/str) and None pass through unchanged
  • list/tuple/dict serialize recursively
  • scalar JAX/NumPy arrays keep the historical float() conversion (backward compatible)
  • everything else falls back to repr() — serialization can never fail a completed run (hence the deliberate broad except: __float__ on arbitrary objects can raise anything)

strategy_parameters therefore always stays JSON-native. Multi-element arrays serialize as their repr() string, not nested lists — lossless array serialization would be a deliberate follow-up, not part of this fix.

Tests

Two regression tests in tests/test_benchmark_result_schema.py drive a fake neural-net object through run_benchmark() as a PolicyStrategy field, asserting the repr fallback, pass-through, recursion, and float paths, plus a full json.dumps round-trip of the resulting BenchmarkResult.

Full suite: 663 passed, 1 skipped.

Note: CI arrives with #100 — merge that first, then update this branch so it gets a CI run before merging.

🤖 Generated with Claude Code

_strategy_parameters() assumed every non-primitive strategy field could
be converted with float(), so a PolicyStrategy holding a neural-network
model (or any other non-numeric object) as a field crashed
run_benchmark() at result-serialization time.

Following the fix suggested in #99: primitives and None pass through,
lists/tuples/dicts serialize recursively, scalar arrays keep the
historical float() conversion, and anything else falls back to repr().
strategy_parameters therefore always stays JSON-native and
serialization never fails a completed run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tim-nish
tim-nish merged commit cf05ccc into main Jul 9, 2026
@tim-nish
tim-nish deleted the fix/issue-99-strategy-parameter-serialization branch July 9, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: _strategy_parameters fails to serialize non-primitive strategy parameters

1 participant