From a8e6f3630b2997eb8addfa41b9f0aef5695137b2 Mon Sep 17 00:00:00 2001 From: suraj-2309 Date: Thu, 27 Nov 2025 13:55:17 +0530 Subject: [PATCH 01/26] Fix test suite failures for serial (DS) and low-budget (NGOpt) optimizers --- .../tests/test_modelfitting_tracefitter.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/brian2modelfitting/tests/test_modelfitting_tracefitter.py b/brian2modelfitting/tests/test_modelfitting_tracefitter.py index a2ccefe..09dea72 100644 --- a/brian2modelfitting/tests/test_modelfitting_tracefitter.py +++ b/brian2modelfitting/tests/test_modelfitting_tracefitter.py @@ -347,15 +347,20 @@ def test_fitter_fit_methods(method): g : siemens (constant) E : volt (constant) ''') + # Fix for optimizers that don't support parallelization (DS) + # or have small fixed budgets (NGOptSingle) + n_samples = 30 + if any(name in method for name in ['DS', 'NGOptSingle']): + n_samples = 1 tf = TraceFitter(dt=dt, model=model, input_var='v', output_var='I', input=input_traces, output=output_traces, - n_samples=30) + n_samples=n_samples) # Skip a few methods that seem to hang due to multi-threading deadlocks (?) or simply take very long - skip = ['BO', 'ParaPortfolio', 'BAR', 'MultiBFGS', 'MultiCobyla', 'MultiSQP', 'NgIohRW', 'F3SQPCMA'] + skip = ['MultiDS', 'BO', 'ParaPortfolio', 'BAR', 'MultiBFGS', 'MultiCobyla', 'MultiSQP', 'NgIohRW', 'F3SQPCMA'] if any(s in method for s in skip): pytest.skip(f'Skipping method {method}') From 619bf0901acc3c61622a7c58c5048da9691950c0 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Thu, 11 Dec 2025 16:30:49 +0100 Subject: [PATCH 02/26] Update sbi support to recent versions --- brian2modelfitting/inferencer.py | 39 +++++++++++---------- brian2modelfitting/tests/test_inferencer.py | 1 - pyproject.toml | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/brian2modelfitting/inferencer.py b/brian2modelfitting/inferencer.py index 43487d6..1915e39 100644 --- a/brian2modelfitting/inferencer.py +++ b/brian2modelfitting/inferencer.py @@ -1,27 +1,31 @@ """ Module to perform simulation-based inference with the ``sbi`` library. """ +import warnings from numbers import Number from typing import Mapping -import warnings +import numpy as np from brian2.core.functions import Function from brian2.core.namespace import get_local_namespace from brian2.core.network import Network from brian2.devices.cpp_standalone.device import CPPStandaloneDevice -from brian2.devices.device import get_device, device +from brian2.devices.device import device, get_device from brian2.equations.equations import Equations from brian2.groups.neurongroup import NeuronGroup from brian2.input.timedarray import TimedArray from brian2.monitors.spikemonitor import SpikeMonitor from brian2.monitors.statemonitor import StateMonitor -from brian2.units.fundamentalunits import (DIMENSIONLESS, - fail_for_dimension_mismatch, - get_dimensions, - Quantity) +from brian2.units.fundamentalunits import ( + DIMENSIONLESS, + Quantity, + fail_for_dimension_mismatch, + get_dimensions, +) from brian2.utils.logger import get_logger + from brian2modelfitting.fitter import get_spikes -import numpy as np + try: import sbi import torch @@ -29,16 +33,17 @@ sbi = None torch = None -from .base import (handle_input_args, - handle_output_args, - handle_param_init, - input_equations, - output_equations, - output_dims) -from .simulator import RuntimeSimulator, CPPStandaloneSimulator +from .base import ( + handle_input_args, + handle_output_args, + handle_param_init, + input_equations, + output_dims, + output_equations, +) +from .simulator import CPPStandaloneSimulator, RuntimeSimulator from .utils import tqdm - logger = get_logger(__name__) @@ -606,9 +611,7 @@ def init_inference(self, inference_method, density_estimator_model, prior, Instantiated inference object. """ import sbi.inference - from sbi.utils.get_nn_models import (posterior_nn, - likelihood_nn, - classifier_nn) + from sbi.neural_nets import classifier_nn, likelihood_nn, posterior_nn try: inference_method = str.upper(inference_method) inference_method_fun = getattr(sbi.inference, inference_method) diff --git a/brian2modelfitting/tests/test_inferencer.py b/brian2modelfitting/tests/test_inferencer.py index 71b10c6..2f6e004 100644 --- a/brian2modelfitting/tests/test_inferencer.py +++ b/brian2modelfitting/tests/test_inferencer.py @@ -319,7 +319,6 @@ def test_infer_step(setup_full): n_samples=10, inference=inference) assert isinstance(posterior, DirectPosterior) - assert_equal(np.array(posterior._x_shape), np.array([1, 5])) def test_infer_step_errors(setup_full): diff --git a/pyproject.toml b/pyproject.toml index b6f4b1a..9ae49d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ algos = [ # additional optimizers for nevergrad 'ConfigSpace'] skopt = ['scikit-optimize'] efel = ['efel'] -sbi = ['sbi>=0.16.0'] +sbi = ['sbi>=0.23.0'] all = ['brian2modelfitting[test]', 'brian2modelfitting[docs]', 'brian2modelfitting[algos]', From f64107ab0abc66e44c167a47786a4a490df211ba Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Thu, 11 Dec 2025 16:38:50 +0100 Subject: [PATCH 03/26] Test Python versions according to SPEC-0 --- .github/workflows/tests.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 885376a..a039159 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,14 +6,37 @@ name: Tests on: [push, pull_request] jobs: + get_python_versions: + name: "Determine Python versions" + runs-on: ubuntu-latest + permissions: {} + outputs: + min-python: ${{ steps.nep29.outputs.min-python }} + max-python: ${{ steps.nep29.outputs.max-python }} + steps: + - name: "calculate versions according to SPEC-0" + id: nep29 + uses: mstimberg/github-calc-nep29@a73481e4e8488a5fa0b3be70a385cc5206a261ba # v0.7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + # Match SPEC-0 + deprecate-python-after: 36 + min-python-releases: 0 + build: - runs-on: ubuntu-latest + needs: [get_python_versions] + name: "Python ${{ matrix.python-version }} (latest Brian: ${{ matrix.latest-brian }})" strategy: fail-fast: false matrix: - python-version: [3.8, 3.11] - latest-brian: [true, false] + include: + - python-version: "${{ needs.get_python_versions.outputs.min-python }}" + latest-brian: false + - python-version: "${{ needs.get_python_versions.outputs.max-python }}" + latest-brian: false + - python-version: "${{ needs.get_python_versions.outputs.max-python }}" + latest-brian: true steps: - name: Checkout Repository From ec32b0390a9e3fa0b44ba5193af8c4789668dec2 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Thu, 11 Dec 2025 16:57:12 +0100 Subject: [PATCH 04/26] Use uv for Python env --- .github/workflows/tests.yml | 31 ++++++++++++++++--------------- pyproject.toml | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a039159..f58d68b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,33 +40,34 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true - name: Install brian2modelfitting - run: | - python -m pip install --upgrade pip wheel - python -m pip install flake8 pytest-coverage pytest-timeout coveralls - python -m pip install ".[all]" + run: uv sync --no-build --all-extras - name: Update to latest Brian development version - run: python -m pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 + run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + # - name: Lint with flake8 + # run: | + # # stop the build if there are Python syntax errors or undefined names + # flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - pytest --timeout=60 --cov=brian2modelfitting + uv run --no-sync --frozen pytest --timeout=60 --cov=brian2modelfitting - name: Upload coverage to coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - if: ${{ matrix.python-version == '3.8' && !matrix.latest-brian }} + if: ${{ matrix.python-version == needs.get_python_versions.outputs.min-python }} run: coveralls --service=github diff --git a/pyproject.toml b/pyproject.toml index 9ae49d4..9548635 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ classifiers = [ ] [project.optional-dependencies] -test = ['pytest'] +test = ['pytest', 'pytest-coverage', 'pytest-timeout'] docs = ['sphinx>=1.8'] algos = [ # additional optimizers for nevergrad 'cma>=3.0', 'fcmaes', 'loguru', # loguru seems to be an undeclared dependency of fcmaes From f3ad81589465c422bcc65220983ad0043fbf7402 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Thu, 11 Dec 2025 16:59:51 +0100 Subject: [PATCH 05/26] Remove `nlopt` (no 3.14 wheels) --- .github/workflows/tests.yml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f58d68b..e5ff57d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,7 +52,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --no-build --all-extras + run: uv sync --all-extras - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} diff --git a/pyproject.toml b/pyproject.toml index 9548635..bb667a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ test = ['pytest', 'pytest-coverage', 'pytest-timeout'] docs = ['sphinx>=1.8'] algos = [ # additional optimizers for nevergrad 'cma>=3.0', 'fcmaes', 'loguru', # loguru seems to be an undeclared dependency of fcmaes - 'nlopt', + # 'nlopt', 'poap', 'ConfigSpace'] skopt = ['scikit-optimize'] From a293d32ca0a4de849d03d2bcb89f2a42deff7866 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Thu, 11 Dec 2025 17:04:58 +0100 Subject: [PATCH 06/26] Update dependencies --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bb667a6..1def27a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,9 +6,9 @@ authors = [ {name = 'Marcel Stimberg'}, {name ='Romain Brette'} ] -requires-python = '>=3.8' +requires-python = '>=3.12' dependencies = [ - 'numpy>=1.21', + 'numpy>=2.0', 'brian2>=2.2', 'nevergrad>=0.4', 'scikit-learn>=0.22', From 22c92e4695814317a04bfc3753423cc95ec2d941 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 17 Dec 2025 17:29:31 +0100 Subject: [PATCH 07/26] Increase timeout for tests --- .github/workflows/tests.yml | 2 +- .../tests/test_modelfitting_tracefitter.py | 51 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e5ff57d..06e7741 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,7 +64,7 @@ jobs: # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - uv run --no-sync --frozen pytest --timeout=60 --cov=brian2modelfitting + uv run --no-sync --frozen pytest --timeout=120 --cov=brian2modelfitting - name: Upload coverage to coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/brian2modelfitting/tests/test_modelfitting_tracefitter.py b/brian2modelfitting/tests/test_modelfitting_tracefitter.py index 09dea72..c3fb03e 100644 --- a/brian2modelfitting/tests/test_modelfitting_tracefitter.py +++ b/brian2modelfitting/tests/test_modelfitting_tracefitter.py @@ -1,23 +1,46 @@ ''' Test the modelfitting module ''' -import pytest +import brian2.numpy_ as np # for unit-awareness import pandas as pd +import pytest import scipy.optimize - -from numpy.testing import assert_equal, assert_almost_equal -from brian2 import (zeros, Equations, NeuronGroup, StateMonitor, TimedArray, - nS, mV, volt, ms, pA, pF, Quantity, set_device, get_device, - Network, have_same_dimensions, DimensionMismatchError) -from brian2.equations.equations import DIFFERENTIAL_EQUATION, SUBEXPRESSION -import brian2.numpy_ as np # for unit-awareness -from brian2modelfitting import (NevergradOptimizer, TraceFitter, MSEMetric, - OnlineTraceFitter, Simulator, Metric, - Optimizer, GammaFactor, FeatureMetric) +from brian2 import ( + DimensionMismatchError, + Equations, + Network, + NeuronGroup, + Quantity, + StateMonitor, + TimedArray, + get_device, + have_same_dimensions, + ms, + mV, + nS, + pA, + pF, + set_device, + volt, + zeros, +) from brian2.devices.device import reinit_devices, reset_device +from brian2.equations.equations import DIFFERENTIAL_EQUATION, SUBEXPRESSION +from numpy.testing import assert_almost_equal, assert_equal + +from brian2modelfitting import ( + FeatureMetric, + GammaFactor, + Metric, + MSEMetric, + NevergradOptimizer, + OnlineTraceFitter, + Optimizer, + Simulator, + TraceFitter, +) from brian2modelfitting.fitter import get_param_dic - E = 40*mV input_traces = zeros((10, 5))*volt for i in range(5): @@ -339,6 +362,8 @@ def test_tracefitter_fit_default_metric(setup): from nevergrad.optimization import registry as nevergrad_registry + + @pytest.mark.parametrize('method', sorted(nevergrad_registry.keys())) def test_fitter_fit_methods(method): dt = 0.01 * ms @@ -1141,7 +1166,7 @@ def test_multiobjective_basic(setup_multiobjective): def test_multiobjective_no_units(setup_multiobjective_no_units): dt, tf = setup_multiobjective_no_units - result, error = tf.fit(n_rounds=20, + result, error = tf.fit(n_rounds=30, metric={'var1': MSEMetric(t_start=50*ms), 'var2': MSEMetric(t_start=50*ms, normalization=0.001)}, optimizer=n_opt, From d2bd0ce74f4dabb57435a63442579faaaac09dc1 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 5 Jan 2026 17:40:34 +0100 Subject: [PATCH 08/26] Do not install sbi and nlopt on Python 3.14 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1def27a..19cc701 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ test = ['pytest', 'pytest-coverage', 'pytest-timeout'] docs = ['sphinx>=1.8'] algos = [ # additional optimizers for nevergrad 'cma>=3.0', 'fcmaes', 'loguru', # loguru seems to be an undeclared dependency of fcmaes - # 'nlopt', + 'nlopt;python_version<"3.14"', 'poap', 'ConfigSpace'] skopt = ['scikit-optimize'] @@ -45,7 +45,7 @@ all = ['brian2modelfitting[test]', 'brian2modelfitting[algos]', 'brian2modelfitting[skopt]', 'brian2modelfitting[efel]', - 'brian2modelfitting[sbi]' + 'brian2modelfitting[sbi];python_version<"3.14"' ] [project.urls] From e261569fc0902a2730fa7bfd695e286b0cd0f13c Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 5 Jan 2026 17:46:36 +0100 Subject: [PATCH 09/26] Remove fcmaes (optional) dependency --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 19cc701..cb107e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ classifiers = [ test = ['pytest', 'pytest-coverage', 'pytest-timeout'] docs = ['sphinx>=1.8'] algos = [ # additional optimizers for nevergrad - 'cma>=3.0', 'fcmaes', 'loguru', # loguru seems to be an undeclared dependency of fcmaes + 'cma>=3.0', 'nlopt;python_version<"3.14"', 'poap', 'ConfigSpace'] From 6d82221bd5c1d9438b79d8e7496df062e6e57527 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 5 Jan 2026 17:47:46 +0100 Subject: [PATCH 10/26] Use a simple matrix for testing --- .github/workflows/tests.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 06e7741..d96bd43 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,13 +30,8 @@ jobs: strategy: fail-fast: false matrix: - include: - - python-version: "${{ needs.get_python_versions.outputs.min-python }}" - latest-brian: false - - python-version: "${{ needs.get_python_versions.outputs.max-python }}" - latest-brian: false - - python-version: "${{ needs.get_python_versions.outputs.max-python }}" - latest-brian: true + python-version: ["${{ needs.get_python_versions.outputs.min-python }}", "${{ needs.get_python_versions.outputs.max-python }}"] + latest-brian: [false, true] steps: - name: Checkout Repository From e4d3a5819177f5d8b58e52656a9583c417fe2715 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Tue, 6 Jan 2026 17:43:15 +0100 Subject: [PATCH 11/26] Do not test on 3.14, do not test efel --- .github/workflows/tests.yml | 8 ++++---- pyproject.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d96bd43..cbc85f6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: permissions: {} outputs: min-python: ${{ steps.nep29.outputs.min-python }} - max-python: ${{ steps.nep29.outputs.max-python }} + max-python: "${{ steps.nep29.outputs.max-python }}" steps: - name: "calculate versions according to SPEC-0" id: nep29 @@ -30,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["${{ needs.get_python_versions.outputs.min-python }}", "${{ needs.get_python_versions.outputs.max-python }}"] + python-version: ["${{ needs.get_python_versions.outputs.min-python }}", "3.13"] latest-brian: [false, true] steps: @@ -47,7 +47,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --all-extras + run: uv sync --extra alogs --extra skopt --extra sbi # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} @@ -63,6 +63,6 @@ jobs: - name: Upload coverage to coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - if: ${{ matrix.python-version == needs.get_python_versions.outputs.min-python }} + if: ${{ matrix.python-version == needs.get_python_versions.outputs.min-python && ! matrix.latest-brian}} run: coveralls --service=github diff --git a/pyproject.toml b/pyproject.toml index cb107e2..3b5f23e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ test = ['pytest', 'pytest-coverage', 'pytest-timeout'] docs = ['sphinx>=1.8'] algos = [ # additional optimizers for nevergrad 'cma>=3.0', - 'nlopt;python_version<"3.14"', + 'nlopt', 'poap', 'ConfigSpace'] skopt = ['scikit-optimize'] @@ -45,7 +45,7 @@ all = ['brian2modelfitting[test]', 'brian2modelfitting[algos]', 'brian2modelfitting[skopt]', 'brian2modelfitting[efel]', - 'brian2modelfitting[sbi];python_version<"3.14"' + 'brian2modelfitting[sbi]' ] [project.urls] From 509d2e7f0f2bb0d1bc8c805366106cffba87e66e Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 11:19:50 +0100 Subject: [PATCH 12/26] fix typo in extra dependency --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cbc85f6..ea83920 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,7 +47,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --extra alogs --extra skopt --extra sbi # Not testing efel for now, since incompatible with numpy 2 + run: uv sync --extra algos --extra skopt --extra sbi # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} From 40fe4825b67c67b92d6f37d0c09ee80fd4e44640 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 11:28:28 +0100 Subject: [PATCH 13/26] Install dev dependencies and lint --- .github/workflows/tests.yml | 10 +++------- pyproject.toml | 3 +++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ea83920..eacd55d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,16 +47,12 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --extra algos --extra skopt --extra sbi # Not testing efel for now, since incompatible with numpy 2 + run: uv sync --extra algos --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} - # - name: Lint with flake8 - # run: | - # # stop the build if there are Python syntax errors or undefined names - # flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Check for syntax errors and undefined names + run: uv run ruff check . --select=E9,F63,F7,F82 - name: Test with pytest run: | uv run --no-sync --frozen pytest --timeout=120 --cov=brian2modelfitting diff --git a/pyproject.toml b/pyproject.toml index 3b5f23e..c1cf67e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,9 @@ all = ['brian2modelfitting[test]', 'brian2modelfitting[sbi]' ] +[dependency-groups] +dev = ['ruff'] + [project.urls] Documentation ='https://brian2modelfitting.readthedocs.io/' Source = 'https://github.com/brian-team/brian2modelfitting' From 738119156f866908692d870f80f76cb695221190 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 11:30:03 +0100 Subject: [PATCH 14/26] Do not test optional algorithms --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index eacd55d..0dd7314 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,7 +47,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --extra algos --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 + run: uv sync --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} From 630fa00df96fc8aa65a44a2668604c1aa7291dfb Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 12:00:31 +0100 Subject: [PATCH 15/26] Verbose install for tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0dd7314..c3d76eb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,7 +47,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 + run: uv sync -v --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} From 5dd154ab566cdeda48d5189c007d5a360a64637f Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 14:31:22 +0100 Subject: [PATCH 16/26] Override torch dependency for now --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index c1cf67e..0b61083 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,9 @@ all = ['brian2modelfitting[test]', [dependency-groups] dev = ['ruff'] +[tool.uv] +override-dependencies = ["torch==2.6.0"] + [project.urls] Documentation ='https://brian2modelfitting.readthedocs.io/' Source = 'https://github.com/brian-team/brian2modelfitting' From e6cfc23fb471147bbf49c897149903e51fb62d78 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 7 Jan 2026 14:31:48 +0100 Subject: [PATCH 17/26] Skip tests requiring efel if not installed --- brian2modelfitting/tests/test_metric.py | 3 +++ brian2modelfitting/tests/test_modelfitting_tracefitter.py | 1 + 2 files changed, 4 insertions(+) diff --git a/brian2modelfitting/tests/test_metric.py b/brian2modelfitting/tests/test_metric.py index 216b0bf..da9845e 100644 --- a/brian2modelfitting/tests/test_metric.py +++ b/brian2modelfitting/tests/test_metric.py @@ -218,6 +218,7 @@ def test_get_errors_gamma(): @pytest.mark.parametrize("parallel_processes", [0, 2, -1, -2]) # only testing that it works at all def test_calc_EFL(parallel_processes): + pytest.importorskip("efel") # "voltage traces" that are constant at -70*mV, -60mV, -50mV, -40mV for # 50ms each. dt = 1*ms @@ -239,6 +240,7 @@ def test_calc_EFL(parallel_processes): def test_get_features_feature_metric(): + pytest.importorskip("efel") # "voltage traces" that are constant at -70*mV, -60mV, -50mV, -40mV for # 50ms each. voltage_target = np.ones((2, 200)) * np.repeat([-70, -60, -50, -40], 50) * mV @@ -276,6 +278,7 @@ def test_get_features_feature_metric(): def test_get_errors_feature_metric(): + pytest.importorskip("efel") # Fake results features = [{'feature1': np.array([0, 0.5]), 'feature2': np.array([1, 2])}, diff --git a/brian2modelfitting/tests/test_modelfitting_tracefitter.py b/brian2modelfitting/tests/test_modelfitting_tracefitter.py index c3fb03e..7e92245 100644 --- a/brian2modelfitting/tests/test_modelfitting_tracefitter.py +++ b/brian2modelfitting/tests/test_modelfitting_tracefitter.py @@ -732,6 +732,7 @@ def test_fitter_refine_reuse_tsteps_multiobjective(setup_constant_multiobjective def test_fitter_refine_errors(setup): + pytest.importorskip("efel") dt, tf = setup with pytest.raises(TypeError): # Missing start parameter From 6697162844a299f8fcd67ec116d4695cb9b98b15 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 12 Jan 2026 15:37:18 +0100 Subject: [PATCH 18/26] =?UTF-8?q?Fix=20`load=5Fposterior`=20for=20torch?= =?UTF-8?q?=E2=89=A52.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- brian2modelfitting/inferencer.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/brian2modelfitting/inferencer.py b/brian2modelfitting/inferencer.py index 1915e39..e0f8ec9 100644 --- a/brian2modelfitting/inferencer.py +++ b/brian2modelfitting/inferencer.py @@ -963,8 +963,15 @@ def load_posterior(self, f): Loaded neural posterior with defined method family, density estimator state dictionary, the prior over parameters and the output shape of the simulator. - """ - p = torch.load(f) + + Notes + ----- + Only use this function to load files from trusted sources. It will + call `torch.load` with ``weights_only=False``, potentially resulting + in arbitrary code execution. See + https://pytorch.org/docs/stable/generated/torch.load.html + """ + p = torch.load(f, weights_only=False) self.posterior = p return p From b2d382ec7fcdb3cad808343cafd417c3513f3a15 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 12 Jan 2026 15:59:58 +0100 Subject: [PATCH 19/26] Avoid numpy 2.4 Some packages Nevergrad depends on are using deprecated features --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0b61083..a816e6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ authors = [ ] requires-python = '>=3.12' dependencies = [ - 'numpy>=2.0', + 'numpy>=2.0,<2.4', # Nevergrad depends on library incompatible with 2.4 'brian2>=2.2', 'nevergrad>=0.4', 'scikit-learn>=0.22', From 643a05ad902aa8b16929cd0d4309debc631fab21 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 12 Jan 2026 16:33:49 +0100 Subject: [PATCH 20/26] Use coveralls action and increase test timeout --- .github/workflows/tests.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c3d76eb..b226ae5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -55,10 +55,7 @@ jobs: run: uv run ruff check . --select=E9,F63,F7,F82 - name: Test with pytest run: | - uv run --no-sync --frozen pytest --timeout=120 --cov=brian2modelfitting + uv run --no-sync --frozen pytest --timeout=240 --cov=brian2modelfitting - name: Upload coverage to coveralls - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6 if: ${{ matrix.python-version == needs.get_python_versions.outputs.min-python && ! matrix.latest-brian}} - run: coveralls --service=github - From 318d00b7d74ea2171f3b06da1ebc40a14c9f6e42 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Mon, 12 Jan 2026 18:41:11 +0100 Subject: [PATCH 21/26] Use lcov format for coverage report --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b226ae5..62b3869 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -55,7 +55,7 @@ jobs: run: uv run ruff check . --select=E9,F63,F7,F82 - name: Test with pytest run: | - uv run --no-sync --frozen pytest --timeout=240 --cov=brian2modelfitting + uv run --no-sync --frozen pytest --timeout=240 --cov=brian2modelfitting --cov-report=lcov - name: Upload coverage to coveralls uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6 if: ${{ matrix.python-version == needs.get_python_versions.outputs.min-python && ! matrix.latest-brian}} From 1733e5b16558b11c2be96d55119dd5bc44b98b11 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Tue, 13 Jan 2026 10:57:48 +0100 Subject: [PATCH 22/26] Test with efel again It should work fine with numpy <2.4 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 62b3869..6543134 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,7 +47,7 @@ jobs: with: enable-cache: true - name: Install brian2modelfitting - run: uv sync -v --extra skopt --extra sbi --extra test --dev # Not testing efel for now, since incompatible with numpy 2 + run: uv sync -v --extra skopt --extra sbi --extra efel --extra test --dev # Not testing efel for now, since incompatible with numpy 2 - name: Update to latest Brian development version run: uv pip install -i https://test.pypi.org/simple/ --pre --upgrade Brian2 if: ${{ matrix.latest-brian }} From 6efe40d876117ccd340047f2b5747d1599162899 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Tue, 13 Jan 2026 17:21:29 +0100 Subject: [PATCH 23/26] Check whether things work for torch < 2.6 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a816e6b..cb0446e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,8 +51,8 @@ all = ['brian2modelfitting[test]', [dependency-groups] dev = ['ruff'] -[tool.uv] -override-dependencies = ["torch==2.6.0"] +# [tool.uv] +# override-dependencies = ["torch==2.6.0"] [project.urls] Documentation ='https://brian2modelfitting.readthedocs.io/' From 2d838626dd8da62e7b9145b77abfa677bbddfeb7 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 14 Jan 2026 10:32:36 +0100 Subject: [PATCH 24/26] Override pytorch dependency for newer Python versions --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cb0446e..00e36e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,8 +51,8 @@ all = ['brian2modelfitting[test]', [dependency-groups] dev = ['ruff'] -# [tool.uv] -# override-dependencies = ["torch==2.6.0"] +[tool.uv] +override-dependencies = ["torch==2.6.0;python_version>='3.13'"] [project.urls] Documentation ='https://brian2modelfitting.readthedocs.io/' From 6e0305131f8e41a9f173d64f2e421be4d3da306c Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 14 Jan 2026 15:39:03 +0100 Subject: [PATCH 25/26] Override sbi's upper version limit for torch --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 00e36e2..94e195b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ all = ['brian2modelfitting[test]', dev = ['ruff'] [tool.uv] -override-dependencies = ["torch==2.6.0;python_version>='3.13'"] +override-dependencies = ["torch"] # Remove sbi's upper dependency [project.urls] Documentation ='https://brian2modelfitting.readthedocs.io/' From e2776cfe56d9c23984c1434bfa62e9dc8c004ca0 Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Wed, 14 Jan 2026 15:56:04 +0100 Subject: [PATCH 26/26] Test again with Python 3.14 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6543134..fc21ddc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["${{ needs.get_python_versions.outputs.min-python }}", "3.13"] + python-version: ["${{ needs.get_python_versions.outputs.min-python }}", "${{ needs.get_python_versions.outputs.max-python }}"] latest-brian: [false, true] steps: