Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]

steps:
- uses: actions/checkout@v7
Expand Down
5 changes: 2 additions & 3 deletions meegkit/asr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import numpy as np
import pyriemann
from pyriemann.geometry.mean import gmean as mean_covariance
from scipy import linalg, signal
from statsmodels.robust.scale import mad
from scipy import linalg, signal, stats

from .utils import block_covariance, nonlinear_eigenspace
from .utils.asr import (
Expand Down Expand Up @@ -407,7 +406,7 @@ def clean_windows(X, sfreq, max_bad_chans=0.2, zthresholds=[-3.5, 5],

# extra meegkit-specific criterion: drop windows whose across-channel
# z-scores are nearly flat (very low MAD or std)
bad_by_mad = mad(wz, c=1, axis=0) < .1
bad_by_mad = stats.median_abs_deviation(wz, axis=0) < .1
bad_by_std = np.std(wz, axis=0) < .1
mask3 = np.logical_or(bad_by_mad, bad_by_std)

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ scikit-learn
pandas
joblib
tqdm
statsmodels
pyriemann>=0.12
22 changes: 22 additions & 0 deletions tests/test_freethreading.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import subprocess
import sys
import sysconfig

import pytest

pytestmark = pytest.mark.skipif(
not sysconfig.get_config_var("Py_GIL_DISABLED"),
reason="requires a free-threaded CPython build",
)


def test_import_does_not_reenable_gil():
# test dependencies (such as pytest extensions) could re-enable the GIL
# without making the library non-freethreaded so we need to run this in
# its own subprocess.
proc = subprocess.run(
[sys.executable, "-c", "import sys, meegkit; assert not sys._is_gil_enabled()"],
capture_output=True,
text=True,
)
assert proc.returncode == 0, proc.stderr