Skip to content

refactor(api)!: the top level holds what you call, and spec, program and errors hold what you get back or catch - #837

Merged
FabianHofmann merged 5 commits into
mainfrom
claude/friendly-planck-fii5ki
Oct 6, 2026
Merged

FabianHofmann merged 5 commits into
mainfrom
claude/friendly-planck-fii5ki

Conversation

@FBumann

@FBumann FBumann commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Prompt: Lets discuss if we should do the same move in mathspec too! And wether we can also scope the program related public api better.

Prompt: But keep the 3 typesetting methods for typst, latex and Md. Before you remove anything program related from the public api, check I specsolve needs it.

Note

The following content was generated by AI.

The top level now holds only what you call. Types move to mathspec.spec and mathspec.program, and errors move to mathspec.errors. tests/test_public_surface.py holds each module to its rule. This is a breaking change for imports.

What moved, what stayed, and why
Module Rule Names
mathspec what you call to_spec, merge, override, advice, typeset, typeset_declaration, to_latex, to_typst, to_markdown, plus SymbolTable and FormatName, which you build or name to pass in
mathspec.spec what the file says Spec, its 21 block classes (the mask blocks from main included), Formulation, Curvature, BUILTIN_NAMES
mathspec.program what the file means unchanged, plus Advice and AdviceKind (now defined there)
mathspec.errors what you catch MathSpecError, LanguageError, SchemaError, DimensionError, did_you_mean

The top level goes from 21 names to 14, and 3 of those are the modules. FORMATS left the top level for FormatName.

  • Not a mathspec.types module. program already is the module for what mathspec gives back. A second such module would draw a line between Spec and Program that a caller cannot predict.
  • Spec does not go into program. spec.py imports program, so program cannot re-export Spec without an import cycle.
  • BUILTIN_NAMES goes to spec, not program. It is the set of operators a file may write. A Program holds no builtin calls.
  • The block classes are now exported. Spec already handed them out through its fields, but no __all__ named them.

Nothing in program was removed. I checked what specsolve uses:

  • parameters_of (4 files under src/) and is_quadratic, walk, assumption_message (also src/).
  • variables_of, carries_variable and children, used by the linopy reference lane under tests/.
  • where_children and walk_regions have no use in specsolve, but reading.md documents them as the traversal API.

Kept on request: to_latex, to_typst and to_markdown.

Not done:

  • The Spec docstring still names three constructors (to_spec, model_validate and Spec(...)).
  • specsolve still imports the old paths. It pins mathspec==0.2.1, so it moves when this is released. That needs a minor version bump.
  • I worked on the session's designated branch, not in a <type>/<topic> worktree.

Docs:

  • api.md lists the top level and errors.
  • New spec.md page, the Spec API, next to the Program API page.
  • New section "Where a name lives" on what-counts-as-public-api.md.
  • Spec.* links now point at spec.md.
Gates

Merged origin/main (1d8ff20: #810, #849, #850) at cbb0614. Conflicts: CHANGELOG.md (both kept) and an import line in tests/test_composition.py. Schema, golden output and the generated pages were regenerated and gave no further diff. The new Missing, MissingReading, RelationMissing and VariableMissing stay in program.__all__.

  • pixi run lint: clean.
  • pixi run ci: clean (2839 passed, 1 skipped; docs-build strict, compile-tex of 54 documents).
Mutation table for the new guards

Each change below was made by hand on the committed tree. I then ran tests/test_public_surface.py and tests/test_docs.py, and restored with git checkout --, removing __pycache__ on both sides. The tree was clean after every probe.

Mutation Caught by
Spec back at the top level, with SURFACE updated to match test_the_top_level_is_what_a_consumer_calls, test_every_name_the_package_exports_has_an_entry_on_an_api_page
a block class in spec.py that is not exported test_the_spec_module_exports_every_class_it_defines
spec re-exports did_you_mean without a pin test_the_spec_module_exports_every_class_it_defines
an error class in errors.py that is not exported test_the_errors_module_exports_the_error_tree
errors exports a helper besides did_you_mean test_the_errors_module_exports_the_error_tree
the top level re-exports typesetting, with both pins updated test_the_top_level_is_what_a_consumer_calls, test_every_name_the_package_exports_has_an_entry_on_an_api_page

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ew8pe1gYVe8MS1ywtF8qUg

…nd errors hold what you get back or catch

`Spec` and its blocks move to `mathspec.spec`, `Advice` and `AdviceKind` to
`mathspec.program`, `BUILTIN_NAMES` to `mathspec.spec`, and the error tree
and `did_you_mean` to `mathspec.errors`. `FORMATS` leaves the top level for
`FormatName`. `tests/test_public_surface.py` holds each module to its rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ew8pe1gYVe8MS1ywtF8qUg
@FBumann
FBumann requested a review from brynpickering as a code owner October 3, 2026 13:21
@read-the-docs-community

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

Copy link
Copy Markdown

@FBumann FBumann added the v0.3.0 label Oct 3, 2026
@FBumann
FBumann requested a review from FabianHofmann October 3, 2026 14:52
@FBumann

FBumann commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

@FabianHofmann We didn't talk about this yet. I think it really cleans up things, but we should discuss it before merging it.

@FBumann FBumann changed the title refactor(api): the top level holds what you call, and spec, program and errors hold what you get back or catch refactor(api)!: the top level holds what you call, and spec, program and errors hold what you get back or catch Oct 6, 2026
The mask blocks join mathspec.spec, test_masks imports LanguageError from
mathspec.errors and FORMATS from mathspec.typesetting.
@FabianHofmann
FabianHofmann merged commit eefa8d2 into main Oct 6, 2026
7 checks passed
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.

3 participants