diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f5afb0be73..b5a8386ccd5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' - uses: pre-commit/action@v3.0.1 - run: pip install mypy numpy scipy vulture - run: mypy @@ -76,15 +76,12 @@ jobs: - os: ubuntu-latest python: '3.13' kind: conda - - os: macos-latest # arm64 (Apple Silicon): Sequoia - python: '3.13' - kind: mamba - - os: macos-15-intel # intel: Sequoia + - os: macos-latest # arm64 + python: '3.14' + kind: pip + - os: macos-15-intel # Intel python: '3.13' - kind: mamba - - os: windows-latest - python: '3.11' - kind: mamba + kind: pip - os: ubuntu-latest python: '3.12' kind: minimal @@ -122,36 +119,21 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - if: startswith(matrix.kind, 'pip') + if: startswith(matrix.kind, 'pip') || matrix.kind == 'minimal' + id: setup-python + # Workaround macOS path behavior with login shells (which puts system Python first) + - run: echo "export PATH=\"$(dirname ${{ steps.setup-python.outputs.python-path }}):$PATH\"" | tee -a ~/.bash_profile # zizmor: ignore[template-injection] + if: startswith(matrix.kind, 'pip') && startswith(matrix.os, 'macos') # Python (if conda) - - name: Fixes for conda - run: | - # 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 - 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@v3 with: environment-file: ${{ env.CONDA_ENV }} environment-name: mne - log-level: ${{ runner.debug == '1' && 'debug' || 'info' }} + log-level: 'info' create-args: >- python=${{ env.PYTHON_VERSION }} -v - if: matrix.kind == 'conda' || matrix.kind == 'mamba' + if: matrix.kind == 'conda' timeout-minutes: 20 # Python (if old) - uses: astral-sh/setup-uv@v8.1.0 @@ -162,7 +144,9 @@ jobs: **/pylock.ci-old.toml python-version: ${{ matrix.python }} if: matrix.kind == 'old' + - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh + timeout-minutes: 10 - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' # Minimal commands on Linux (macOS stalls) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3413eb5c391..3802be37719 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -82,9 +82,9 @@ stages: variables: AZURE_CI: 'true' jobs: - - job: Ultraslow_PG + - job: Linux_Ultraslow_PG pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-latest' variables: DISPLAY: ':99' OPENBLAS_NUM_THREADS: '1' @@ -93,7 +93,7 @@ stages: MNE_BROWSER_PRECOMPUTE: 'false' steps: - bash: | - set -e + set -eo pipefail ./tools/setup_xvfb.sh sudo apt install -yq tcsh displayName: 'Install Ubuntu dependencies' @@ -112,19 +112,19 @@ stages: addToPath: true displayName: 'Get Python' - bash: | - set -e + set -eo pipefail python -m pip install --progress-bar off --upgrade pip python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git" pyvista scikit-learn python-picard qtpy nibabel sphinx-gallery "PySide6!=6.8.0,!=6.8.0.1,!=6.8.1.1,!=6.9.1" pandas neo pymatreader antio defusedxml curryreader pymef python -m pip uninstall -yq mne python -m pip install --progress-bar off --upgrade -e . --group=test displayName: 'Install dependencies with pip' - bash: | - set -e + set -eo pipefail mne sys_info -pd mne sys_info -pd | grep "qtpy .*(PySide6=.*)$" displayName: Print config - bash: | - set -e + set -eo pipefail LD_DEBUG=libs python -c "from PySide6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()" - bash: source tools/get_testing_version.sh displayName: 'Get testing version' @@ -141,19 +141,10 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - - job: Qt + - job: Linux_Qt_Bindings pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-latest' variables: DISPLAY: ':99' OPENBLAS_NUM_THREADS: '1' @@ -169,7 +160,7 @@ stages: addToPath: true displayName: 'Get Python' - bash: | - set -e + set -eo pipefail python -m pip install --progress-bar off --upgrade pip python -m pip install --progress-bar off --upgrade --pre --only-binary=\"numpy,scipy,matplotlib,vtk\" numpy scipy matplotlib vtk python -c "import vtk" @@ -223,15 +214,6 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - job: Windows pool: @@ -250,9 +232,9 @@ stages: strategy: maxParallel: 4 matrix: - 3.10 pip: + 3.11 pip: TEST_MODE: 'pip' - PYTHON_VERSION: '3.10' + PYTHON_VERSION: '3.11' 3.13 pip pre: TEST_MODE: 'pip-pre' PYTHON_VERSION: '3.13' @@ -292,12 +274,3 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName) $(TEST_MODE) $(PYTHON_VERSION)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' diff --git a/environment.yml b/environment.yml index 4bc85279dc8..00982630e41 100644 --- a/environment.yml +++ b/environment.yml @@ -5,6 +5,7 @@ channels: dependencies: - python >=3.10 - antio >=0.5.0 + - conda - curryreader >=0.1.2 - darkdetect - decorator >=5.1 @@ -29,9 +30,11 @@ dependencies: - matplotlib >=3.8 - mffpy >=0.5.7 - mne-qt-browser + - nest-asyncio2 - nibabel >=2.0 - nilearn - nomkl + - noqt5 - numba >=0.35 - numpy >=1.26,<3 - openmeeg >=2.5.7 @@ -43,7 +46,7 @@ dependencies: - pyarrow - pybv - pymatreader - - PySide6 !=6.9.1 + - PySide6 ==6.10.2 - python-neo - python-picard >=0.4 - pyvista >=0.43 @@ -61,9 +64,8 @@ dependencies: - trame - trame-vtk - trame-vuetify - - vtk >=9.2 + - vtk ==9.6.0 - xlrd - pip: - - nest-asyncio2 - pymef - pyobjc-framework-Cocoa >=5.2.0;platform_system=='Darwin' diff --git a/mne/conftest.py b/mne/conftest.py index 85a1e72e9f8..2c2ee028b79 100644 --- a/mne/conftest.py +++ b/mne/conftest.py @@ -213,6 +213,7 @@ def pytest_configure(config: pytest.Config): # VTK <-> NumPy 2.5 (https://gitlab.kitware.com/vtk/vtk/-/merge_requests/12796) # nitime <-> NumPy 2.5 (https://github.com/nipy/nitime/pull/236) ignore:Setting the shape on a NumPy array has been deprecated.*:DeprecationWarning + ignore:Implicitly cleaning up.*:ResourceWarning """ # noqa: E501 for warning_line in warning_lines.split("\n"): warning_line = warning_line.strip() diff --git a/mne/tests/test_source_estimate.py b/mne/tests/test_source_estimate.py index 41e33c52274..2dfd3bb04d4 100644 --- a/mne/tests/test_source_estimate.py +++ b/mne/tests/test_source_estimate.py @@ -1983,7 +1983,7 @@ def test_scale_morph_labels(kind, scale, monkeypatch, tmp_path): min_, max_ = 0.72, 0.76 else: # min_, max_ = 0.84, 0.855 # zooms='auto' values - min_, max_ = 0.46, 0.63 + min_, max_ = 0.44, 0.63 assert min_ < corr <= max_, scale else: assert_allclose(label_tc, label_tc_to_morph, atol=1e-12, rtol=1e-12) diff --git a/mne/viz/tests/test_evoked.py b/mne/viz/tests/test_evoked.py index 9071bb8971c..c1e88acc1ef 100644 --- a/mne/viz/tests/test_evoked.py +++ b/mne/viz/tests/test_evoked.py @@ -373,6 +373,7 @@ def test_plot_white_rank(): evoked.plot_white(cov, rank=rank) +@pytest.mark.slowtest def test_plot_white(): """Test plot_white.""" cov = read_cov(cov_fname) diff --git a/tools/environment_minimal.yml b/tools/environment_minimal.yml deleted file mode 100644 index f67decbe0d2..00000000000 --- a/tools/environment_minimal.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: mne -channels: - - conda-forge -dependencies: - - python>=3.9 - - pip - - numpy - - scipy - - matplotlib - - tqdm - - pooch - - decorator - - packaging - - jinja2 - - lazy_loader diff --git a/tools/get_minimal_commands.sh b/tools/get_minimal_commands.sh index ff8ada7741d..1145ae5822c 100755 --- a/tools/get_minimal_commands.sh +++ b/tools/get_minimal_commands.sh @@ -79,4 +79,3 @@ which mne_surf2bem mne_surf2bem --version which mri_average mri_average --version -set +x diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 8621a7a9709..3ee5986cfa9 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -3,31 +3,27 @@ set -eo pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +ONLY_BINARY_ARG="--only-binary=numpy,scipy,matplotlib,numba,llvmlite,antio" STD_ARGS="--progress-bar off --upgrade" INSTALL_ARGS="-e" if [ ! -z "$CONDA_ENV" ]; then echo "Uninstalling MNE for CONDA_ENV=${CONDA_ENV}" - # This will fail if mne-base is not in the env (like in our minimal env, so ||true them): echo "::group::Uninstalling MNE" - conda remove -c conda-forge --force -yq mne-base || true - python -m pip uninstall -y mne || true + conda remove -c conda-forge --force -y mne-base echo "::endgroup::" - # If using bare environment.yml and not on windows, do a non-editable install - if [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${CONDA_ENV}" != "environment_"* ]]; then + # If not on windows, do a non-editable install + if [[ "${CI_OS_NAME}" != "windows"* ]]; then INSTALL_ARGS="" fi - # If on minimal, just install testing deps - if [[ "${MNE_CI_KIND}" == "minimal" ]]; then - GROUP="test" - EXTRAS="" - STD_ARGS="--progress-bar off ${MNE_QT_BACKEND}" - echo "::group::Upgrading pip installation" - python -m pip install --upgrade pip # upgrade pip to support --group - echo "::endgroup::" - else - GROUP="test_extra" - EXTRAS="[hdf5]" - fi + GROUP="test_extra" + EXTRAS="[hdf5]" +elif [[ "${MNE_CI_KIND}" == "minimal" ]]; then + GROUP="test" + EXTRAS="" + STD_ARGS="--progress-bar off ${MNE_QT_BACKEND}" + echo "::group::Upgrading pip installation" + python -m pip install --upgrade pip setuptools + echo "::endgroup::" elif [[ "${MNE_CI_KIND}" == "old" ]]; then GROUP="" # group "test" already included when pylock file generated EXTRAS="" @@ -39,10 +35,12 @@ elif [[ "${MNE_CI_KIND}" == "old" ]]; then elif [[ "${MNE_CI_KIND}" == "pip" ]]; then GROUP="test_extra" EXTRAS="[full-pyside6]" + python -m pip install --upgrade pip setuptools else test "${MNE_CI_KIND}" == "pip-pre" + python -m pip install $STD_ARGS pip setuptools STD_ARGS="$STD_ARGS --pre" - ${SCRIPT_DIR}/install_pre_requirements.sh || exit 1 + ${SCRIPT_DIR}/install_pre_requirements.sh GROUP="test_extra" EXTRAS="" fi @@ -61,6 +59,5 @@ else echo "::group::Installing MNE in development mode using pip" fi set -x -python -m pip install $STD_ARGS $INSTALL_ARGS .$EXTRAS $GROUP_ARG -set +x +python -m pip install $STD_ARGS $ONLY_BINARY_ARG $INSTALL_ARGS .$EXTRAS $GROUP_ARG echo "::endgroup::" diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index c518e982276..cf4d6eaa3c0 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -1,37 +1,34 @@ #!/bin/bash -set -eo pipefail -x +set -eo pipefail # old and minimal use conda -if [[ "$MNE_CI_KIND" == "pip"* ]]; then +if [[ "$MNE_CI_KIND" == "pip"* ]] || [[ "$MNE_CI_KIND" == "minimal" ]]; then echo "Setting pip env vars for $MNE_CI_KIND" if [[ "$MNE_CI_KIND" == "pip-pre" ]]; then - echo "MNE_QT_BACKEND=PyQt6" | tee -a $GITHUB_ENV # We should test an eager import somewhere, might as well be here echo "EAGER_IMPORT=true" | tee -a $GITHUB_ENV # Make sure nothing unexpected is skipped echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|Numba not|PySide6 causes segfaults).*" | tee -a $GITHUB_ENV - else - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV fi + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_IGNORE_WARNINGS_IN_TESTS=true" | tee -a $GITHUB_ENV echo "MNE_SKIP_NETWORK_TESTS=1" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV -else # conda-like +elif [[ "$MNE_CI_KIND" == "conda" ]]; then echo "Setting conda env vars for $MNE_CI_KIND" - if [[ "$MNE_CI_KIND" == "minimal" ]]; then - echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV - else # conda, mamba (use warning level for completeness) - echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV - echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV - # TODO: Also need "|unreliable on GitHub Actions conda" on macOS, but omit for now to make sure the failure actually shows up - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior).*" | tee -a $GITHUB_ENV - # Our cache_dir test has problems when the path is too long, so prevent it from getting too long - if [[ "$RUNNER_OS" == "macOS" ]]; then - echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV - fi + echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV + echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior).*" | tee -a $GITHUB_ENV + # Our cache_dir test has problems when the path is too long, so prevent it from getting too long + if [[ "$CI_OS_NAME" == "macos"* ]]; then + echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV fi + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV +else + echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" + exit 1 +fi +if [[ "$CI_OS_NAME" == "windows"* ]]; then + echo "MNE_IS_OSMESA=true" | tee -a $GITHUB_ENV fi -set +x diff --git a/tools/github_actions_test.sh b/tools/github_actions_test.sh index 202b041bc79..ea4d783acea 100755 --- a/tools/github_actions_test.sh +++ b/tools/github_actions_test.sh @@ -4,8 +4,18 @@ set -eo pipefail if [[ "${CI_OS_NAME}" == "ubuntu"* ]]; then CONDITION="not (ultraslowtest or pgtest)" -else # macOS or Windows +elif [[ "${CI_OS_NAME}" == "macos"* ]]; then + # detect arch and run slowtest on arm64 only (pgtest is already ultraslow on macOS) + if [[ "$(uname -m)" == "arm64" ]]; then + CONDITION="not (ultraslowtest or pgtest)" + else + CONDITION="not (slowtest or pgtest)" + fi +elif [[ "${CI_OS_NAME}" == "windows"* ]]; then CONDITION="not (slowtest or pgtest)" +else + echo "✕ ERROR: Unrecognized CI_OS_NAME=${CI_OS_NAME}" + exit 1 fi if [ "${MNE_CI_KIND}" == "notebook" ]; then USE_DIRS=mne/viz/ @@ -13,7 +23,7 @@ else USE_DIRS="mne/" fi JUNIT_PATH="junit-results.xml" -if [[ ! -z "$CONDA_ENV" ]] && [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${MNE_CI_KIND}" != "minimal" ]] && [[ "${MNE_CI_KIND}" != "old" ]]; then +if [[ ! -z "$CONDA_ENV" ]] && [[ "${CI_OS_NAME}" != "windows"* ]] && [[ "${MNE_CI_KIND}" != "minimal" ]] && [[ "${MNE_CI_KIND}" != "old" ]]; then PROJ_PATH="$(pwd)" JUNIT_PATH="$PROJ_PATH/${JUNIT_PATH}" # Use the installed version after adding all (excluded) test files diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh new file mode 100755 index 00000000000..c33a5cdec93 --- /dev/null +++ b/tools/github_actions_verify_python.sh @@ -0,0 +1,40 @@ +#!/bin/bash -ef + +set -eo pipefail + +WANT_PYTHON_VERSION="$1" +if [[ -z "$WANT_PYTHON_VERSION" ]]; then + echo "✕ ERROR: Missing required argument: want Python version (e.g., 3.10)" + exit 1 +fi + +GOT_PYTHON=$(which python) +GOT_PYTHON_VERSION=$(python --version) +echo "Checking Python found at:" +echo " \$(which python) == ${GOT_PYTHON}" +echo " \$(python --version) == ${GOT_PYTHON_VERSION}" +echo "for" +echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" +if [[ "${MNE_CI_KIND}" == "conda" ]]; then + WANT="micromamba/envs/mne" +elif [[ "${MNE_CI_KIND}" == "old" ]]; then + WANT="mne-python/mne-python/.venv/bin" +elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]] || [[ "${MNE_CI_KIND}" == "minimal" ]]; then + WANT="/hostedtoolcache/" +else + echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" + exit 1 +fi +if [[ "${GOT_PYTHON}" != *"${WANT}"* ]]; then + echo "✕ ERROR: Did not find \"${WANT}\" from PATH:" + tr ':' '\n' <<< "$PATH" + exit 1 +else + echo "☑ Found expected \"${WANT}\"" +fi +if [[ "${GOT_PYTHON_VERSION}" != *"${WANT_PYTHON_VERSION}"* ]]; then + echo "✕ ERROR: Did not find expected Python version \"${WANT_PYTHON_VERSION}\"" + exit 1 +else + echo "☑ Found expected Python version \"${WANT_PYTHON_VERSION}\"" +fi \ No newline at end of file diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index da4b3e6eb46..ba822baa651 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -22,8 +22,10 @@ deps |= set(section_deps) recursive_deps = set(d for d in deps if d.startswith("mne[")) deps -= recursive_deps -deps |= {"pip", "mamba", "nomkl"} -deps -= {"nest-asyncio2", "pymef"} # not on conda-forge +deps |= {"pip", "mamba", "conda", "nomkl", "noqt5"} +# not on conda-forge +pip_deps = {"pymef"} +deps -= pip_deps def remove_spaces(version_spec): @@ -47,30 +49,35 @@ def split_dep(dep): # split package name from version spec translations = dict(neo="python-neo") -pip_deps = {" - nest-asyncio2", " - pymef"} -conda_deps = set() +conda_dep_lines = set() +version_spec_overrides = { + # Help the solver work faster by specifying these (should be updated periodically): + "PySide6": "==6.10.2", + "vtk": "==9.6.0", +} +for key in version_spec_overrides: + assert any(dep.startswith(key) for dep in deps), ( + f"Need to adjust code below if {key} is not a dependency: {deps}" + ) for dep in deps: package_name, version_spec = split_dep(dep) + version_spec = version_spec_overrides.get(package_name, version_spec) # 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. 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` == "" line = f" - {package_name} {version_spec}".rstrip() # use pip for packages needing e.g. `platform_system` or `python_version` triaging if ";" in version_spec: - pip_deps.add(f" {line}") + pip_deps.add(line[4:]) else: - conda_deps.add(line) + conda_dep_lines.add(line) # prepare the pip dependencies section newline = "\n" # python < 3.12 forbids backslash in {} part of f-string pip_section = f"""\ - pip: -{newline.join(sorted(pip_deps, key=str.casefold))} +{newline.join(sorted((f" - {dep}" for dep in pip_deps), key=str.casefold))} """ pip_section = pip_section if len(pip_deps) else "" # prepare the env file @@ -81,7 +88,7 @@ def split_dep(dep): - conda-forge dependencies: - python {req_python} -{newline.join(sorted(conda_deps, key=str.casefold))} +{newline.join(sorted(conda_dep_lines, key=str.casefold))} {pip_section}""" # noqa: E501 (repo_root / "environment.yml").write_text(env) diff --git a/tools/install_pre_requirements.sh b/tools/install_pre_requirements.sh index 9977a01c9d4..093940e193a 100755 --- a/tools/install_pre_requirements.sh +++ b/tools/install_pre_requirements.sh @@ -7,7 +7,9 @@ PLATFORM=$(python -c 'import platform; print(platform.system())') echo "Installing pip-pre dependencies on ${PLATFORM}" STD_ARGS="--progress-bar off --upgrade --pre" -QT_BINDING="PySide6" +if [[ "$MNE_QT_BACKEND" == "" ]]; then + MNE_QT_BACKEND="PySide6" +fi # Dependencies of scientific-python-nightly-wheels are installed here so that # we can use strict --index-url (instead of --extra-index-url) below @@ -16,7 +18,7 @@ echo "::group::Prerequisites" python -m pip install $STD_ARGS pip setuptools packaging \ threadpoolctl cycler fonttools kiwisolver pyparsing pillow python-dateutil \ patsy pytz tzdata nibabel tqdm trx-python joblib numexpr \ - "$QT_BINDING!=6.9.1" \ + "$MNE_QT_BACKEND!=6.9.1" \ py-cpuinfo blosc2 hatchling "formulaic>=1.1.0" \ matplotlib python -m pip uninstall -yq numpy @@ -69,5 +71,5 @@ python -c "import numpy as np; assert np.__version__[0] == '2', np.__version__" echo "::endgroup::" echo "::group::Check Qt import" -${SCRIPT_DIR}/check_qt_import.sh "$QT_BINDING" +${SCRIPT_DIR}/check_qt_import.sh "$MNE_QT_BACKEND" echo "::endgroup::"