Skip to content

feat(spec): a loaded spec holds each dims: list and each side of a relation sorted by name - #916

Closed
FBumann wants to merge 3 commits into
feat/dims-sorted-by-namefrom
feat/spec-sorts-lists
Closed

FBumann wants to merge 3 commits into
feat/dims-sorted-by-namefrom
feat/spec-sorts-lists

Conversation

@FBumann

@FBumann FBumann commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Prompt: Would all of this get easier if we sort etc in the spec itself ?

Prompt: I think sorting in spec is more truthfull overall...

Prompt: i think if the typesetting etc can folloow the orer of a user, this is actually valueable...

Note

The following content was generated by AI.

A Spec now sorts each dims: list and each side of a relation as it loads. Their order reaches nothing a consumer reads since #914. Entries keep the file's order, because the typeset document prints them in it.

Stacked on #914.

What this changes

Order Who sees it In the spec
entries in a section the typeset document, which prints them in that order kept as the file lists them
a dims: list nobody, since #914 sorted by name as it loads
a relation's key: and values: nobody, since #914 each side sorted by role as it loads, the key first
  • Two files that differ only in a list's order load to equal specs, not only equal programs, and to_yaml() writes back one text.
  • to_yaml() writes those lists sorted. The author's order of a dims: list is not kept, because it says nothing.
  • The program, the namespace and the canonical form read the lists as the spec holds them, and no longer sort them again. That is 8 sorts in _lowering.py, 3 in _resolution.py's leaf dims, _sorted_columns, the canonical form's dims sort and its _sorted_side.
  • The reading guide and the glossary say which orders a Spec keeps and which it sorts.
Method, gate output, mutation table

Method. One annotated type, Dims = Annotated[list[str], AfterValidator(sorted)], on the nine dims fields. One field validator on RelationSpec.key and .values, which sorts a list and a mapping by role and leaves a single column alone. The JSON schema is unchanged. No code builds a spec model with model_construct or model_copy(update=...), so every spec model passes through the validators.

Three relation-key sorts in _condition_resolver.py stay. They sort the dimensions of the key's columns, not the roles, and a key may name one dimension twice.

Tests.

  • New: test_the_order_a_file_writes_a_list_in_reaches_no_value_of_the_spec runs on every example. It reverses every dims: list and each side of a relation, and asserts an equal Spec and an equal to_yaml().
  • Eight tests expected a spec's dims in the order the file wrote them, and now expect them sorted. They are in test_composition, test_conditions, test_given and test_piecewise. The expanded weights of a curve list the breakpoint dimension where its name sorts, not last.
  • Three tests in test_pypsa_collapses.py said a frame gains a leading scenario or period. They now say it gains scenario or period, and compare sorted lists.

Gates on afe9235:

  • pixi run lint: passed.
  • pixi run test: 3322 passed, 1 skipped.
  • pixi run docs-build: passed.
  • Every generator re-run: only docs/examples/library/composed.md changed, where the merged spec now lists its dims sorted.
  • compile-tex: did not run here. Tectonic could not download its bundle in the sandbox. CI runs it.

Mutation table. Each change was made by hand, and the full suite ran. The file was restored with git checkout --, and __pycache__ was dropped before and after each run. The tree came back clean each time.

Change Caught by
a dims: list kept as written 447 failures, among them test_a_file_written_backwards_writes_the_same_text
a relation's sides kept as written 47 failures
a relation side written as a mapping kept as written 31 failures, among them test_a_file_written_backwards_writes_the_same_text[generator_maintenance]
Not done
  • Entries keep the file's order in the spec, the program and the typeset document. Only the canonical form sorts them, so that two files that state one spec write one text.
  • The source files in examples/ keep their authors' list order. They are inputs, not written output.
  • The writer PR (fields as set, the canonical form without defaults, composition by value) is stacked on this one, and loses its own dims sort in composition here.

Generated by Claude Code

…lation sorted by name

Their order reaches nothing a consumer reads since the program sorts
them, so the spec sorts them once as it loads, and every reader after it
reads them as they are. A spec keeps its entries in the order its file
lists them, because the typeset document prints them in that order.

Two files that differ only in a list's order load to equal specs and
write back one text. The program, the namespace and the canonical form
no longer sort them again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NNjZXCjH1FpCvxUvDGjWNw
@FBumann
FBumann added this pull request to stack #917 October 20, 2026 19:40
@read-the-docs-community

read-the-docs-community Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

FBumann commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Prompt: Could it be condensed into less PRs? Its too chaotic for me atm

Note

The following content was generated by AI.

Superseded by #924, which squashes #914, #916 and #921 into one commit on main. The branch is kept, because #918 still targets it until #918 is moved onto #924.


Generated by Claude Code

@FBumann FBumann closed this Oct 21, 2026
FBumann pushed a commit that referenced this pull request Oct 21, 2026
Each conflict resolves to the tree of #921's head, which already held
#914, #916, #918 and #921 together. The changelog keeps #918's line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019j1TmBS3MvzmuarWjhCHHu
@FBumann
FBumann removed this pull request from stack #917 October 21, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants