Skip to content
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
# Full Python range on Linux; a single Python on macOS/Windows to catch
# OS-specific issues at low runner cost.
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
include:
- { os: macos-latest, python-version: "3.12" }
- { os: windows-latest, python-version: "3.12" }
Expand All @@ -35,6 +35,11 @@ jobs:
cache: pip
cache-dependency-path: pyproject.toml

# swiglpk (a cobra/optlang dependency) publishes no Python 3.15 wheel, so pip
# builds it from source, which needs the GLPK headers and SWIG.
- name: Install GLPK build dependencies
if: matrix.python-version == '3.15'
run: sudo apt-get update && sudo apt-get install -y libglpk-dev swig
- name: Install
run: pip install -e ".[dev,evotune]"

Expand Down
2 changes: 1 addition & 1 deletion examples/ecTestGEM/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ def get_spontaneous_reactions(self, model: "cobra.Model") -> list[str]:
# reordering by cobrapy's SBML parser.
if "R4" in {r.id for r in model.reactions}:
return ["R4"]
return []
return []
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
"Topic :: Scientific/Engineering :: Bio-Informatics",
]
dependencies = [
Expand Down
4 changes: 3 additions & 1 deletion src/geckopy/gather_kcats/kcat_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ def _okp_method(name: str, wanted: dict[str, Any]) -> str:


def _same(a: Any, b: Any) -> bool:
norm = (lambda v: v.lower() if isinstance(v, str) else (int(v) if isinstance(v, bool) else v))
def norm(v: Any) -> Any:
return v.lower() if isinstance(v, str) else (int(v) if isinstance(v, bool) else v)

return norm(a) == norm(b)


Expand Down
1 change: 0 additions & 1 deletion src/geckopy/gather_kcats/kcat_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"""
from __future__ import annotations

import json
import logging
import math
import re
Expand Down
1 change: 0 additions & 1 deletion tests/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ def _schema_leaves(model_cls, prefix=""):
from pydantic import BaseModel

leaves = {}
instance = model_cls.model_construct()
for name, field in model_cls.model_fields.items():
key = f"{prefix}{name}"
annotation = field.annotation
Expand Down
1 change: 0 additions & 1 deletion tests/test_conc_control_coeffs_shadow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import sys
from types import SimpleNamespace

import numpy as np
import pytest

from geckopy.limit_proteins import get_conc_control_coeffs
Expand Down
1 change: 0 additions & 1 deletion tests/test_parity_fixes_g1a.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Behaviour that follows GECKO: truncate_values ties, the detail text of a kcat source file,
and the defaults of fill_kcats_from_isozymes."""
import numpy as np
import pandas as pd
import pytest

from geckopy.ec_model.pipeline import fill_kcats_from_isozymes, set_kcat_for_reactions
Expand Down
1 change: 0 additions & 1 deletion tests/test_review_fixes_r1p.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Edge cases of get_conc_control_coeffs, fit_sigma and the docstring of fill_kcats_from_isozymes."""
import numpy as np
import pytest

from geckopy.kcat_tuning import fit_sigma
Expand Down
Loading