Split gems into gems_craft/gems_runner (alternative to #243)#244
Open
aoustry wants to merge 2 commits into
Open
Split gems into gems_craft/gems_runner (alternative to #243)#244aoustry wants to merge 2 commits into
aoustry wants to merge 2 commits into
Conversation
Splits the monolithic gems package along a solver-dependency boundary instead of a parsing-vs-everything boundary: - gems_craft: the resolved domain model (Model, Library, System, Component, PortsConnection), YAML schema/parsing, and the structural half of the expression language (AST, parsing, linearity/indexing analysis). No solver dependency - installable and importable with only numpy, pandas, PyYAML, pydantic, anytree, and antlr4-python3-runtime. - gems_runner: solve-time execution - expression evaluation (evaluate.py), session, simulation, study.runner, and the gemspy CLI. Depends on gems_craft plus a new `runner` extra (linopy, xarray, highspy). This keeps gems_craft usable as a standalone base for editing, validating, and querying systems (e.g. an API layer) without pulling in the optimization solver stack, which the prior split (PR #243) did not allow since it placed System/Component/Model and the whole expression package under the solver-dependent side. Verified: gems_craft imports cleanly in a clean venv with no runner extra installed; mypy clean; full pytest suite passes unchanged (541 passed, 6 skipped, 1 xfailed). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C635KKMQurDjEBS3qXBqpA
CI was still installing deps without the new `runner` optional-dependency extra, so mypy failed resolving gems_runner's linopy/xarray/highspy imports. The pytest step also still referenced the old `gems` package name for coverage. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C635KKMQurDjEBS3qXBqpA
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.
Process ID
Process: GP-01
Description
Alternative split of the monolithic
gemspackage intogems_craftandgems_runner, proposed as a counter-option to #243.Both PRs agree on the goal: separate the solver-independent parts of GEMS from solve-time execution. They disagree on where the line goes.
#243's boundary is parsing vs. everything else.
gems_craftthere contains only the Pydantic YAML-schema layer (*Schemaclasses). The resolved domain objects —Model,Library,System,Component,PortsConnection— and the entireexpression/package (AST, parsing, linearity/indexing analysis) all move togems_runner, bundled with the solver.This PR's boundary is solver-dependency, not parsing.
gems_craftcontains everything with no dependency onlinopy/xarray/highspy:model/(Model,Library,Port*,Constraint,Parameter,Variable),study/minusrunner.py(System,Component,PortsConnection,Study,DataBase,resolve_components.py,folder.py,scenario_builder.py)optim_config/(pure Pydantic +TYPE_CHECKING-only refs, no solver import)expression/— AST, parsing,degree.py/is_linear,indexing.py,uses_sum_connections_on.py— everything exceptevaluate.pygems_runneris left with only genuinely solve-time code:expression/evaluate.py(itsdual()/reduced_cost()/variable()handlers are solver-output-shaped, not general-purpose math — the one deliberate exception),simulation/*,session/*,study/runner.py, and thegemspyCLI (main/).Why this matters: a
System/ComponentCRUD-and-query API (editing systems, filtering components by properties, walking peer components through port connections) needs the resolved domain model, not the raw parsed schema. Under #243's split, building that API ongems_craftwould require depending ongems_runner— pulling in the solver stack just to read/edit a system. Under this split,gems_craftis a complete, self-contained base for that API.Packaging: kept as a single distribution (one
pyproject.toml), not a two-wheel monorepo — lower risk, no CI/tooling restructuring.linopy/xarray/highspymove to a newrunneroptional-dependency extra sopip install gemspyalone never pulls in the solver stack, verified by installinggems_craftin a clean venv with zero extras and importing it successfully.Impact Analysis
expression/,model/,study/,optim_config/,simulation/,session/,main/are all affected — file moves only, no logic changes. Everygems.*import acrosssrc/andtests/was mechanically rewritten togems_craft.*/gems_runner.*.gems_runner.expression.evaluategained two absolute imports (gems_craft.expression.expression,.indexing,.visitor) in place of what were same-package relative imports in the monolith, sinceevaluate.pynow lives in a different package than the rest ofexpression/.pyproject.toml:dependenciestrimmed togems_craft's actual deps (numpy,pandas,PyYAML,pydantic,anytree,antlr4-python3-runtime); added[project.optional-dependencies].runnerforlinopy/xarray/highspy;gemspyscript entry point repointed togems_runner.main.main:main_cli;[tool.mypy]packages/overrides updated..github/workflows/ci.yml: install step now requests--extra runner; coverage flags updated from--cov gemsto--cov gems_craft --cov gems_runner.Checklist
pytest) — 547 passed, 1 xfailed (full suite incl.--group solvers)mypy) — 60 source files, cleanblack,isort)pyproject.tomlversion bumped if applicable — left alone perdocs/agents/python-convention.md(version bumps are handled via thefeat(release):commit workflow, not manual edits); changelog entry added under[Unreleased]AGENTS.mdreviewed for impact and updated if needed — architecture section rewritten for the two-package structureGenerated by Claude Code