Repository navigation
feat(api): an axis is written as plain data with to_dict, and solve_over takes that data in its place - #1981
Merged
Merged
Conversation
…ver takes that data in its place Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS
Merging this PR will not alter performance
Comparing Footnotes
|
…ere it carries something Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS
FBumann
added this pull request to stack #1986
October 12, 2026 06:36
This was referenced Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
EachCoordinate.to_dict()andEachWindow.to_dict()write an axis as plain data, carry included.solve_overtakes that mapping in the axis's place. An archive'saxis.jsonis the same mapping, so the browser app can solve from it without importingspecsolve.axes.The shape, and why it matches the rest of the API
Spec.to_dict()writes it, andto_spec,check,buildandsolvetake the mapping in its place. There is no public reader function.axis_fromstays private, assolve_over's reader and the archive's.json.dumps(axis.to_dict())is the JSON form. The spec hasto_yamlbecause its file is YAML; an axis lives inaxis.json.axis_fromreads the keys an axis takes and the ones it needs offdataclasses.fields, so a field added to an axis is accepted and named in refusals with no second list to update.eachpicks the class from one table,_EACH.CARRY. Its parameters and variables are keys inside it, and a dimension's name is always a value, so no name in a spec can collide with the format: a dimension calledstepsand a carry of{'steps': ..., 'dim': ...}read back equal.eachthat names no axis, a key the axis does not take, and a key it needs and lacks each raiseSpecsolveErrorbefore a slice is taken. For example:EachWindow given as a mapping takes 'each' and ['dim', 'steps', 'lookahead', 'into', 'carry'], of which ['dim', 'steps', 'lookahead', 'into'] are required: ['lookahead'] is missing.carrykey where nothing is carried, so an archive'saxis.jsonstays byte-identical andINPUTS_LAYOUTstays at 1. A test holds the literal dict.axis_manifestis gone: the archive writesaxis.to_dict().Mutation table, full suite
I took these by hand, because each is a substitution: committed tree,
git checkout --restore,__pycache__dropped on both sides, tree checked clean after every run. The first four were taken onab3f613. The last was taken again on8a558c0, afterto_dictwas rewritten.axis_from: no refusal of aneachthat names no axis…refused_with_the_keys_it_takes[no-each],[an-each-that-names-no-axis]axis_from: unknown keys not looked for[a-key-the-axis-does-not-take]axis_from: missing keys not looked for[a-key-the-axis-needs]solve_over: the mapping not read as an axistest_solve_over_takes_an_axis_as_its_dictand the four refusal casesto_dict: thecarrykey written even when empty (if self.carry→if True)test_an_axis_that_carries_nothing_writes_no_carry_keyThe last test was written for that mutation. The round-trip and archive tests would not catch it, because both sides go through
to_dict.Gates, and what was not done
8a558c0.pixi run check: lint, format and typecheck clean, 5621 passed, 566 skipped, 4 xfailed.pixi run -e docs docs-test: 112 passed, so the new docstring links resolve.pixi run -e docs docs-buildpassed, strict, onab3f613; the later commit touches no page.load_archiveandload_inputsstill give the axis back as an object, not a dict. feat(api): a sweep can be cut by several axes at once, each carrying its own state, such as a rolling horizon per scenario or a pathway whose decades roll through their hours #1888 adds a tuple of axes; when it merges this in,to_dictandaxis_fromneed a form for the tuple. Theeachkey and its two values are still string literals, into_dictand_EACH. The browser app's worker is not changed here.🤖 Generated with Claude Code
https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS