@@ -247,9 +247,10 @@ To maintain backward compatibility, we'll keep the existing module-level lists b
247247``` python
248248# These are generated from the registry for backward compatibility
249249QUADRATIC_SOLVERS = get_solvers_with_feature(SolverFeature.QUADRATIC_OBJECTIVE )
250- QUADRATIC_CONSTRAINT_SOLVERS = get_solvers_with_feature(SolverFeature.QUADRATIC_CONSTRAINTS )
251- NONCONVEX_QUADRATIC_CONSTRAINT_SOLVERS = get_solvers_with_feature(SolverFeature.NONCONVEX_QUADRATIC_CONSTRAINTS )
252250NO_SOLUTION_FILE_SOLVERS = get_solvers_with_feature(SolverFeature.SOLUTION_FILE_NOT_NEEDED )
251+
252+ # Derived (filtered by availability) - also generated from registry
253+ quadratic_solvers = get_available_solvers_with_feature(SolverFeature.QUADRATIC_OBJECTIVE )
253254```
254255
255256No deprecation warnings - these lists remain fully supported and are simply generated from the registry now.
@@ -269,17 +270,25 @@ Create `linopy/solver_capabilities.py` with:
269270### Step 2: Update ` solvers.py `
270271
271272- Import the new module
272- - Generate existing lists from registry (backward compat)
273- - Add deprecation warnings to direct list access (optional)
273+ - Generate existing lists from registry (backward compat):
274+ - ` QUADRATIC_SOLVERS `
275+ - ` NO_SOLUTION_FILE_SOLVERS `
276+ - ` quadratic_solvers ` (filtered by availability)
274277
275278### Step 3: Update ` model.py `
276279
277280Replace:
278281``` python
279- # Before
282+ # Before (model.py:1199)
280283if solver_name in NO_SOLUTION_FILE_SOLVERS :
284+
285+ # Before (model.py:1211)
281286if solver_name not in quadratic_solvers:
287+
288+ # Before (model.py:1234)
282289if solver_name in [" glpk" , " cbc" ]:
290+
291+ # Before (model.py:1342)
283292if solver_name in [" gurobi" , " xpress" ]:
284293```
285294
@@ -292,41 +301,38 @@ if not solver_supports(solver_name, SolverFeature.LP_FILE_NAMES):
292301if solver_supports(solver_name, SolverFeature.IIS_COMPUTATION ):
293302```
294303
295- ### Step 4: Update ` io.py `
296-
297- Replace hardcoded solver checks with capability checks.
298-
299- ### Step 5: Update ` variables.py `
304+ ### Step 4: Update ` variables.py `
300305
301306Replace:
302307``` python
303- if solver == " gurobi" :
308+ # Before (variables.py:852)
309+ if self .model.solver_name != " gurobi" :
304310```
305311
306312With:
307313``` python
308- if solver_supports(solver, SolverFeature.SOLVER_ATTRIBUTE_ACCESS ):
314+ # After
315+ if not solver_supports(self .model.solver_name, SolverFeature.SOLVER_ATTRIBUTE_ACCESS ):
309316```
310317
311- ### Step 6 : Update Tests
318+ ### Step 5 : Update Tests (optional for POC)
312319
313320- Update test parametrization to use ` get_available_solvers_with_feature() `
314321- Replace hardcoded solver lists in test files
315322
323+ Note: ` io.py ` doesn't need changes - the check at line 508 (` "highs" not in available_solvers ` ) is about package availability, not solver features.
324+
316325---
317326
318327## File Changes Summary
319328
320329| File | Changes |
321330| ------| ---------|
322- | ` linopy/solver_capabilities.py ` | ** NEW** - Core registry module |
323- | ` linopy/solvers.py ` | Import registry, generate compat lists |
324- | ` linopy/model.py ` | Replace ~ 6 hardcoded checks |
325- | ` linopy/io.py ` | Replace ~ 3 hardcoded checks |
331+ | ` linopy/solver_capabilities.py ` | ** NEW** - Core registry module (~ 150 lines) |
332+ | ` linopy/solvers.py ` | Import registry, generate compat lists (~ 10 lines changed) |
333+ | ` linopy/model.py ` | Replace 4 hardcoded checks |
326334| ` linopy/variables.py ` | Replace 1 hardcoded check |
327- | ` linopy/__init__.py ` | Export ` SolverFeature ` , ` solver_supports ` |
328- | ` test/test_optimization.py ` | Update solver parametrization |
329- | ` test/test_quadratic_constraint.py ` | Update solver parametrization |
335+ | ` linopy/__init__.py ` | Export ` SolverFeature ` , ` solver_supports ` (optional) |
330336
331337---
332338
@@ -404,11 +410,9 @@ If we decide to extract this to a separate package:
404410## Implementation Order
405411
4064121 . Create ` solver_capabilities.py ` with full registry
407- 2 . Add backward compatibility exports to ` solvers.py ` (generate lists from registry)
408- 3 . Update ` model.py ` (highest impact - ~ 6 checks)
409- 4 . Update ` io.py ` (~ 3 checks)
410- 5 . Update ` variables.py ` (1 check)
411- 6 . Update test files to use registry helpers
412- 7 . Run tests and verify everything works
413-
414- Estimated scope: ~ 300-400 lines of new code, ~ 50 lines modified across existing files.
413+ 2 . Update ` solvers.py ` to generate lists from registry
414+ 3 . Update ` model.py ` (4 checks)
415+ 4 . Update ` variables.py ` (1 check)
416+ 5 . Run tests and verify everything works
417+
418+ Estimated scope: ~ 150 lines of new code, ~ 20 lines modified across existing files.
0 commit comments