Repository navigation
Simplify linopy.spec: one constructor, data in model.parameters, no accessor - #1068
Merged
Merged
Conversation
Keep every parameter unfilled in ModelSpec.parameters and fill on read; drop the .spec stamp, presence dataset, add_spec, lower_text and the file-name sniffing of str specs. Public surface is ModelSpec, NamedExpression, SpecDataError, Declaration and attach. Notebook updated.
4 of 5 tasks
from_spec writes raw parameters and relations into model.parameters; linopy.spec.evaluate and linopy.spec.parameter replace ModelSpec. Object parameters round-trip netcdf with NaN holes; grid sources accept NaN as a missing row; sets, extension arrays and named value columns are accepted; str file names are refused with a Path hint. Docs: spec-data page.
A hole in a refused parameter is excused where where: masks, a masked variable, an absent row, an unfilled shift edge or a failed lookup make the term absent anyway. build and evaluate share one check that names the parameter, the declaration and the missing labels.
This was referenced Oct 27, 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.
Stack 2/2, depends on #958
Changes proposed in this Pull Request
Three commits over
linopy/spec/on top of #958. The first (commit 09fd02e) trimmed the accessor: one constructor, no stamp, no presence dataset. The second (commit e87a489) removes the accessor entirely after an API review: a spec-built model is a plain linopy model whose data lives inmodel.parameters, and results come from two functions of(spec, model). The spec feature is unreleased, so nothing is deprecated; it is removed.What changed for the user
Model.from_spec(spec, sources, **model_kwargs)is the only entry point.Model.add_specandmodel.specare gone. Astris YAML text; a file goes in as aPath, and a one-linestrending in.yaml/.ymlraises aValueErrorthat says so.model.parameters.from_specwrites every parameter unfilled (NaN holes, int/bool with holes as float) and every relation intomodel.parametersunder their declared names. Model-wide operations such asassign_coords,copyand the netcdf round trip therefore apply to the spec data for free.linopy.spec.evaluate(spec, model, *names) -> dict[str, DataArray]folds the named expressions over the solution and the parameters.linopy.spec.parameter(spec, model, name)returns the filled values with the declared dtype.linopy.spec.__all__isSpecDataError,evaluate,parameter.mathspec.typeset(spec, fmt)andtypeset_linereplacemodel.spec.typeset()anddeclaration(). The undeclared-name warning is gone with the accessor.Model.from_spec(path, read_netcdf(f).parameters)rebuilds a model without the original sources.missing:policy; long tables still refuse it. A long table may carry its values in a column named after the parameter. Sets, extension arrays, Categorical and masked indexes work as dimension sources. Each source key is read once, so a lazyMappingruns one query per parameter. Labels that differ only by type get a "differ in type, not spelling" error with a datetime hint.synthetic_sourcesinlinopy.testingtakes every spec formfrom_spectakes.missing: refusedonly raises for demanded holes (commit 746f873). A hole is excused where the term is absent anyway: awhere:mask, a masked variable, anabsentrow of another parameter, an unfilled shift edge or a failed lookup. Build andevaluateshare one check that names the parameter, the declaration and the missing labels.parameter()returns NaN at excused holes.Changes for all models
''.['a', 1]) now raise on write instead of being silently written as strings.read_netcdfkeeps parameter coordinates that no data variable uses.Docs
New page
doc/spec-data.rst(source contract, SQLite example, holes, rebuild, variants via mathspec). Notebook,doc/api.rst,doc/user-guide.rstand the release notes are updated.API review findings deferred to issues
Updating data and re-solving (editing
model.parameterschangesevaluatebut not the model); applying a spec to an existing model and composing programs; bare relations and sets derived from data; sparse data densified; data-only named expressions not inmodel.expressions; lazy per-parameter reads.Checklist
AGENTS.md).doc.doc/release_notes.rstof the upcoming release is included.