diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fd6070e29b2..aefead6199f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -50,7 +50,7 @@ jobs: pytest: name: '${{ matrix.os }} / ${{ matrix.kind }} / ${{ matrix.python }}' needs: style - timeout-minutes: 90 + timeout-minutes: 120 runs-on: ${{ matrix.os }} defaults: run: @@ -78,7 +78,7 @@ jobs: - os: macos-latest # arm64 (Apple Silicon): Sequoia python: '3.13' kind: mamba - - os: macos-14 # arm64 (Apple Silicon): Sonoma + - os: macos-15-intel # intel: Sequoia python: '3.13' kind: mamba - os: windows-latest @@ -128,12 +128,18 @@ jobs: # For some reason on Linux we get crashes if [[ "$RUNNER_OS" == "Linux" ]]; then sed -i "/numba/d" environment.yml + fi # And on Windows and macOS PySide6.9.0 segfaults - elif [[ "$RUNNER_OS" == "macOS" ]]; then - sed -i "" "s/ - PySide6 .*/ - PySide6 =6.7.3/g" environment.yml - sed -i "" "s/ - vtk .*/ - vtk =9.3.1/g" environment.yml - elif [[ "$RUNNER_OS" == "Windows" ]]; then - sed -i "s/ - PySide6 .*/ - PySide6 <6.8/g" environment.yml + if [[ "$RUNNER_OS" == "macOS" ]]; then + sed -i "" "s/ - PySide6 .*/ - PySide6 =6.9.2/g" environment.yml + sed -i "" "s/ - vtk .*/ - vtk =9.5.1/g" environment.yml + + else + sed -i "s/ - PySide6 .*/ - PySide6 =6.9.2/g" environment.yml + sed -i "s/ - vtk .*/ - vtk =9.5.1/g" environment.yml + if [[ "$RUNNER_OS" == "Windows" ]]; then + echo "MNE_IS_OSMESA=true" | tee -a $GITHUB_ENV + fi fi if: matrix.kind == 'conda' || matrix.kind == 'mamba' - uses: mamba-org/setup-micromamba@v2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 71d16ca6246..9930f29fbb7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: # Ruff mne - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.13.1 + rev: v0.13.2 hooks: - id: ruff-check name: ruff lint mne @@ -82,7 +82,7 @@ repos: # zizmor - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.13.0 + rev: v1.14.2 hooks: - id: zizmor diff --git a/doc/sphinxext/related_software.py b/doc/sphinxext/related_software.py index 41a8c43ca1a..01ad35632b7 100644 --- a/doc/sphinxext/related_software.py +++ b/doc/sphinxext/related_software.py @@ -33,7 +33,6 @@ "meggie", "niseq", "sesameeg", - "invertmeeg", } # If it's not available on PyPI, add it to this dict: diff --git a/environment.yml b/environment.yml index 30036dc8187..4586093473c 100644 --- a/environment.yml +++ b/environment.yml @@ -62,3 +62,5 @@ dependencies: - trame-vuetify - vtk >=9.2 - xlrd + - pip: + - pyobjc-framework-Cocoa >=5.2.0;platform_system=='Darwin' diff --git a/mne/conftest.py b/mne/conftest.py index fd50f48299d..cc5eb89bba5 100644 --- a/mne/conftest.py +++ b/mne/conftest.py @@ -199,6 +199,11 @@ def pytest_configure(config: pytest.Config): ignore:.*The `disp` and `iprint` options of the L-BFGS-B solver.*:DeprecationWarning # matplotlib<->nilearn ignore:[\S\s]*You are using the 'agg' matplotlib backend[\S\s]*:UserWarning + # matplotlib<->pyparsing + ignore:^'.*' argument is deprecated, use '.*'$:DeprecationWarning + ignore:^'.*' deprecated - use '.*'$:DeprecationWarning + # dipy + ignore:'where' used without 'out', expect .*:UserWarning """ # noqa: E501 for warning_line in warning_lines.split("\n"): warning_line = warning_line.strip() diff --git a/mne/decoding/tests/test_receptive_field.py b/mne/decoding/tests/test_receptive_field.py index 70d46a170fa..db2209f4695 100644 --- a/mne/decoding/tests/test_receptive_field.py +++ b/mne/decoding/tests/test_receptive_field.py @@ -238,9 +238,9 @@ def test_receptive_field_basic(n_jobs): rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats - with pytest.raises(ValueError, match="`estimator` must be a float or"): + with pytest.raises((ValueError, AttributeError)): ReceptiveField(tmin, tmax, 1, estimator="foo").fit(X, y) - with pytest.raises(ValueError, match="`estimator` must be a float or"): + with pytest.raises((ValueError, AttributeError)): ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])).fit(X, y) with pytest.raises(ValueError, match="tmin .* must be at most tmax"): ReceptiveField(5, 4, 1).fit(X, y) diff --git a/mne/viz/backends/_pyvista.py b/mne/viz/backends/_pyvista.py index 794908e6e3c..66d05df5b73 100644 --- a/mne/viz/backends/_pyvista.py +++ b/mne/viz/backends/_pyvista.py @@ -8,6 +8,7 @@ # License: BSD-3-Clause # Copyright the MNE-Python contributors. +import os import platform import re import warnings @@ -1331,6 +1332,8 @@ def _is_osmesa(plotter): # and a working Nouveau is: "Mesa 24.2.3-1ubuntu1 via NVE6" if platform.system() == "Darwin": # segfaults on macOS sometimes return False + if os.getenv("MNE_IS_OSMESA", "").lower() == "true": + return True gpu_info_full = plotter.ren_win.ReportCapabilities() gpu_info = re.findall( "OpenGL (?:version|renderer) string:(.+)\n", diff --git a/mne/viz/backends/tests/test_renderer.py b/mne/viz/backends/tests/test_renderer.py index 88506bae210..09833c6d503 100644 --- a/mne/viz/backends/tests/test_renderer.py +++ b/mne/viz/backends/tests/test_renderer.py @@ -226,6 +226,7 @@ def test_3d_warning(renderer_pyvistaqt, monkeypatch): bad = f"{pre}OpenGL 3.3 (Core Profile) Mesa 18.3.4 via llvmpipe (LLVM 7.0, 256 bits)\n" # noqa monkeypatch.setattr(platform, "system", lambda: "Linux") # avoid short-circuit monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: good) + monkeypatch.setenv("MNE_IS_OSMESA", "false") assert _is_osmesa(plotter) monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: bad) with pytest.warns(RuntimeWarning, match=r"18\.3\.4 is too old"): diff --git a/tools/circleci_dependencies.sh b/tools/circleci_dependencies.sh index 99ac770a34a..33801c7dbd4 100755 --- a/tools/circleci_dependencies.sh +++ b/tools/circleci_dependencies.sh @@ -14,6 +14,6 @@ python -m pip install --upgrade --progress-bar off \ mne-icalabel mne-lsl mne-microstates mne-nirs mne-rsa \ neurodsp neurokit2 niseq nitime pactools mnelab \ plotly pycrostates pyprep pyriemann python-picard sesameeg \ - sleepecg tensorpac yasa meegkit eeg_positions wfdb invertmeeg \ + sleepecg tensorpac yasa meegkit eeg_positions wfdb \ curryreader python -m pip install --upgrade --progress-bar off --no-deps cross-domain-saliency-maps diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 70fe84509ab..4e7300cd40b 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -17,6 +17,8 @@ if [ ! -z "$CONDA_ENV" ]; then if [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${CONDA_ENV}" != "environment_"* ]]; then INSTALL_ARGS="" fi + # TODO: Until a PyVista release supports VTK 9.5+ + STD_ARGS="$STD_ARGS https://github.com/pyvista/pyvista/archive/refs/heads/main.zip" # If on minimal or old, just install testing deps if [[ "${CONDA_ENV}" == "environment_"* ]]; then INSTALL_KIND="test" diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 39a1a29eddd..0f38daaaf28 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -53,7 +53,8 @@ def split_dep(dep): # handle package name differences package_name = translations.get(package_name, package_name) # PySide6==6.7.0 only exists on PyPI, not conda-forge, so excluding it in - # `environment.yaml` breaks the solver + # `environment.yaml` breaks the solver. 6.9.1 has a bug, and 6.9.2 needs newer + # C deps that mean we need to upgrade VTK etc. if package_name == "PySide6": version_spec = "!=6.9.1" # rstrip output line in case `version_spec` == "" @@ -64,10 +65,6 @@ def split_dep(dep): else: conda_deps.add(line) -# TODO: temporary workaround while we wait for a release containing the fix for -# https://github.com/mamba-org/mamba/issues/3467 -pip_deps.remove(" - pyobjc-framework-Cocoa >=5.2.0;platform_system=='Darwin'") - # prepare the pip dependencies section newline = "\n" # python < 3.12 forbids backslash in {} part of f-string pip_section = f"""\