Skip to content

feat(composition): rename gives a spec other names - #1002

Merged
FabianHofmann merged 6 commits into
mainfrom
claude/jolly-carson-jr9crk
Nov 12, 2026
Merged

FabianHofmann merged 6 commits into
mainfrom
claude/jolly-carson-jr9crk

Conversation

@FabianHofmann

@FabianHofmann FabianHofmann commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Note

The following content was generated by AI.

Supersedes #905: the same rename, on current main, without the PyPSA YAML work.

What this changes

mathspec.rename(source, names) returns a spec with other names, so one fragment states several components in one merge. names is a map or a function.

# before: one hand-written file per component
ms.merge(['network.yaml', 'gas.yaml', 'wind.yaml'])

# after: one fragment, renamed by a rule (or by a map)
def named(prefix, dim):
    def new_name(name):
        if name == 'unit':
            return dim
        return prefix + name.removeprefix('Unit') if name.startswith('Unit_') else None
    return new_name

ms.merge(['network.yaml', ms.rename('unit.yaml', named('Gas', 'gas')), ms.rename('unit.yaml', named('Wind', 'wind'))])
ms.rename('generator.yaml', {'Generator_p_nom': 'Generator_capacity'})

Why

Method, gate output, alternatives
  • gate: pixi run lint (with pyrefly), test (4197 passed, 1 skipped), docs-build exit 0 on 4b9ea22; compile-tex passed on 3cd3e97, no file under examples/ changed since
  • not run: specsolve parity harness
  • renamed: entry keys, dims:, relation sides, a relation column named after its dimension, adds_to:, given: entries, name tokens in expression, where:, bound, case, assumption and macro template text
  • kept: description, one_of: labels, case and link names, macro arguments, fixed choices, call keywords, quoted labels, numbers
  • a map value of None or of the same name keeps the name, as in the function form
  • refused before any rename: a key the spec lacks; a new name already in use; two names on one; a new name that is a macro argument where the template uses the old name; a name to or from a relation column not named after its dimension; names neither a map nor a function (TypeError)
  • fresh review by a separate agent found the last three; each reproduced, then fixed with a test; each guard removed in turn fails its test
  • ported from feat(composition): rename gives a spec other names, so one fragment can serve several classes in one merge #905 to main: conditions: for masks:, frozen sorted sections; one_of: labels and link names stay as written
  • sweep, not in the suite: 58 files under examples/ rename to a prefix and back to the same canonical form
  • docs: how-to section with the steps; composition.md has a rename section with what it changes and keeps, and each refusal quoted whole; page examples and messages run and match
  • no figure for rename: it changes names, not rows
  • prose checked against the prose-writing and docs-writing skills; compose.md: 51 sentences, average 10.6 words; composition.md: 113, average 13.9; none over 25
  • not done: renaming inside description:; merge still names a renamed spec by its place, such as '#2'; a quoted label that ends in \ inside an expression is not handled like the parser does (not reproduced)

`rename(source, names)` replaces each name wherever the spec writes it:
entry keys, dims, relation sides, adds_to, given entries, and every name
token in expression, where, bound, case and assumption text. Descriptions,
`one_of:` labels, case and link names, macro formals, fixed choices,
keywords, quoted labels and numbers stay. A map that names nothing the spec
has, takes a name the spec keeps, or lands two names on one is refused.

`names` is a map, or a function that is called once with each name the
spec declares or reads under `given:` and returns the new name or `None`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWCCJEPW1t29RgovRT4w6t
Claude-Session: https://claude.ai/code/session_01F4nx8Ha7yrYAkVax434rAf
Docstrings, the two refusal messages and the how-to section use flat
verbs for a spec, "lists under given:" as the other pages do, and
"components" in place of "classes". The map example ends with a
sentence that reads its result.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F4nx8Ha7yrYAkVax434rAf
`docs/reference/composition.md` has a `rename` section: what it changes
and keeps, the two forms of `names`, and each refusal quoted whole. The
how-to and the API page link to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F4nx8Ha7yrYAkVax434rAf
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F4nx8Ha7yrYAkVax434rAf
@read-the-docs-community

read-the-docs-community Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

A new name that a macro uses as an argument, where the template uses
the old name, and a name that is also a relation column not named after
its dimension, both changed an expression without a refusal. rename now
refuses both. A name mapped to None or to itself is kept in a map as in
a function, and names that are neither raise TypeError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F4nx8Ha7yrYAkVax434rAf
@FabianHofmann

Copy link
Copy Markdown
Contributor Author

I would deliberately merge this as this is super useful for the pypsa pr. Hope that works out

@FabianHofmann
FabianHofmann merged commit cc53115 into main Nov 12, 2026
7 checks passed
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.

2 participants