diff --git a/.github/workflows/doc.yaml b/.github/workflows/doc.yaml index c6d2c3750..3daee9cc4 100644 --- a/.github/workflows/doc.yaml +++ b/.github/workflows/doc.yaml @@ -12,39 +12,28 @@ jobs: build: timeout-minutes: 30 runs-on: ubuntu-latest - defaults: - run: - shell: bash steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: path: ./main - - name: Setup Python 3.9 - uses: actions/setup-python@v5 + - uses: actions/setup-python@v5 with: - python-version: 3.9 - architecture: 'x64' + python-version: 3.13 - name: Install linux dependencies run: | sudo apt update sudo apt install optipng - - name: Setup headless display - uses: pyvista/setup-headless-display-action@main + - uses: pyvista/setup-headless-display-action@main with: qt: true - name: Install package run: | python -m pip install --progress-bar off --upgrade pip setuptools python -m pip install --progress-bar off main/.[doc] - - name: Display system information - run: mne_icalabel-sys_info --developer - - name: Build doc - run: sphinx-build ./main/doc ./doc-build/dev -W --keep-going - - name: Prune sphinx environment - run: sudo rm -R ./doc-build/dev/.doctrees - - name: Upload documentation - uses: actions/upload-artifact@v4 + - run: mne_icalabel-sys_info --developer + - run: sphinx-build ./main/doc ./doc-build/dev -W --keep-going + - run: sudo rm -R ./doc-build/dev/.doctrees + - uses: actions/upload-artifact@v4 with: name: doc-dev path: ./doc-build/dev @@ -56,19 +45,13 @@ jobs: runs-on: ubuntu-latest permissions: contents: write - defaults: - run: - shell: bash steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Download documentation - uses: actions/download-artifact@v4 + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 with: name: doc-dev path: ./doc-dev - - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4 + - uses: JamesIves/github-pages-deploy-action@v4 with: folder: ./doc-dev target-folder: ./dev diff --git a/.github/workflows/draft-pdf.yml b/.github/workflows/draft-pdf.yml index a055d000a..be48771e5 100644 --- a/.github/workflows/draft-pdf.yml +++ b/.github/workflows/draft-pdf.yml @@ -9,19 +9,12 @@ jobs: runs-on: ubuntu-latest name: Paper Draft steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Build draft PDF - uses: openjournals/openjournals-draft-action@master + - uses: actions/checkout@v4 + - uses: openjournals/openjournals-draft-action@master with: journal: joss - # This should be the path to the paper within your repo. paper-path: paper/paper.md - - name: Upload - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v4 with: name: paper - # This is the output path where Pandoc will write the compiled - # PDF. Note, this should be the same directory as the input - # paper.md path: paper/paper.pdf diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 812643476..fc588dab8 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -9,25 +9,19 @@ jobs: timeout-minutes: 10 runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Python 3.9 - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.9' - architecture: 'x64' - - name: Setup headless display - uses: pyvista/setup-headless-display-action@main + python-version: '3.13' + - uses: pyvista/setup-headless-display-action@main with: qt: true - name: Install dependencies run: | python -m pip install --progress-bar off --upgrade pip setuptools python -m pip install --progress-bar off -e .[build,stubs] - - name: Display system information - run: mne_icalabel-sys_info --developer - - name: Generate stub files - run: python tools/stubgen.py + - run: mne_icalabel-sys_info --developer + - run: python tools/stubgen.py - name: Build and publish env: TWINE_USERNAME: __token__ diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index 630fd6bbe..1d13f3ed8 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -17,33 +17,27 @@ jobs: fail-fast: false matrix: os: [ubuntu, macos, windows] - python-version: [3.9, "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12", "3.13"] name: ${{ matrix.os }} - py${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest defaults: run: shell: bash steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Setup headless display - uses: pyvista/setup-headless-display-action@main + - uses: pyvista/setup-headless-display-action@main with: qt: true - name: Install package run: | python -m pip install --progress-bar off --upgrade pip setuptools python -m pip install --progress-bar off .[test] - - name: Display system information - run: mne_icalabel-sys_info --developer - - name: Run pytest - run: pytest mne_icalabel --cov=mne_icalabel --cov-report=xml --cov-config=pyproject.toml - - name: Upload to codecov - uses: codecov/codecov-action@v5 + - run: mne_icalabel-sys_info --developer + - run: pytest mne_icalabel --cov=mne_icalabel --cov-report=xml --cov-config=pyproject.toml + - uses: codecov/codecov-action@v5 with: files: ./coverage.xml flags: unittests # optional @@ -59,18 +53,12 @@ jobs: python-version: ["3.11"] name: pip pre-release - py${{ matrix.python-version }} runs-on: ubuntu-latest - defaults: - run: - shell: bash steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Setup headless display - uses: pyvista/setup-headless-display-action@main + - uses: pyvista/setup-headless-display-action@main with: qt: true - name: Install dependencies @@ -80,12 +68,9 @@ jobs: python -m pip install --progress-bar off --upgrade git+https://github.com/mne-tools/mne-python python -m pip install --progress-bar off --upgrade git+https://github.com/mne-tools/mne-bids python -m pip install --progress-bar off --upgrade --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --timeout=180 numpy scipy matplotlib - - name: Display system information - run: mne_icalabel-sys_info --developer - - name: Run pytest - run: pytest mne_icalabel --cov=mne_icalabel --cov-report=xml --cov-config=pyproject.toml - - name: Upload to codecov - uses: codecov/codecov-action@v5 + - run: mne_icalabel-sys_info --developer + - run: pytest mne_icalabel --cov=mne_icalabel --cov-report=xml --cov-config=pyproject.toml + - uses: codecov/codecov-action@v5 with: files: ./coverage.xml flags: unittests # optional diff --git a/.github/workflows/stubs.yaml b/.github/workflows/stubs.yaml index ebaf8d29a..37be092cf 100644 --- a/.github/workflows/stubs.yaml +++ b/.github/workflows/stubs.yaml @@ -12,29 +12,20 @@ jobs: generate: timeout-minutes: 10 runs-on: ubuntu-latest - defaults: - run: - shell: bash steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Python 3.9 - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: 3.9 - architecture: 'x64' - - name: Setup headless display - uses: pyvista/setup-headless-display-action@main + python-version: 3.13 + - uses: pyvista/setup-headless-display-action@main with: qt: true - name: Install package run: | python -m pip install --progress-bar off --upgrade pip setuptools python -m pip install --progress-bar off -e .[stubs] - - name: Display system information - run: mne_icalabel-sys_info --developer - - name: Generate stub files - run: python tools/stubgen.py + - run: mne_icalabel-sys_info --developer + - run: python tools/stubgen.py - name: Push stub files if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' env: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3983ae5a6..90f4232f0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.11.13 + rev: v0.12.0 hooks: - id: ruff name: ruff linter diff --git a/doc/conf.py b/doc/conf.py index a0879db7e..35b636542 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -9,7 +9,6 @@ import sys from datetime import date from importlib import import_module -from typing import Optional import mne from sphinx_gallery.sorting import FileNameSortKey @@ -260,7 +259,7 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/linkcode.html -def linkcode_resolve(domain: str, info: dict[str, str]) -> Optional[str]: +def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None: """Determine the URL corresponding to a Python object. Parameters diff --git a/mne_icalabel/annotation/bids.py b/mne_icalabel/annotation/bids.py index 881a1d40f..525d176dd 100644 --- a/mne_icalabel/annotation/bids.py +++ b/mne_icalabel/annotation/bids.py @@ -10,12 +10,11 @@ if TYPE_CHECKING: from pathlib import Path - from typing import Union from mne.preprocessing import ICA -def write_components_tsv(ica: ICA, fname: Union[str, Path]): +def write_components_tsv(ica: ICA, fname: str | Path): """Write channels tsv file for ICA components. Will create an accompanying JSON sidecar to explain the @@ -102,7 +101,7 @@ def write_components_tsv(ica: ICA, fname: Union[str, Path]): def mark_component( component: int, - fname: Union[str, Path], + fname: str | Path, method: str, label: str, author: str, diff --git a/mne_icalabel/config.py b/mne_icalabel/config.py index e3cfab016..3965243db 100644 --- a/mne_icalabel/config.py +++ b/mne_icalabel/config.py @@ -5,9 +5,9 @@ from .iclabel import iclabel_label_components if TYPE_CHECKING: - from typing import Callable, Optional + from collections.abc import Callable -ICALABEL_METHODS: dict[str, Optional[Callable]] = { +ICALABEL_METHODS: dict[str, Callable | None] = { "iclabel": iclabel_label_components, "manual": None, } diff --git a/mne_icalabel/config.pyi b/mne_icalabel/config.pyi index 42b5d55e6..e7f36f817 100644 --- a/mne_icalabel/config.pyi +++ b/mne_icalabel/config.pyi @@ -1,4 +1,4 @@ -from typing import Callable +from collections.abc import Callable from .iclabel import iclabel_label_components as iclabel_label_components diff --git a/mne_icalabel/datasets/icalabel/icalabel.py b/mne_icalabel/datasets/icalabel/icalabel.py index 96ad626a0..4334d0c23 100644 --- a/mne_icalabel/datasets/icalabel/icalabel.py +++ b/mne_icalabel/datasets/icalabel/icalabel.py @@ -11,14 +11,13 @@ if TYPE_CHECKING: from pathlib import Path - from typing import Optional has_icalabel_testing_data = partial(has_dataset, name="icalabel-testing") @verbose def data_path( - path: Optional[str] = None, + path: str | None = None, force_update: bool = False, update_path: bool = True, download: bool = True, diff --git a/mne_icalabel/features/topomap.py b/mne_icalabel/features/topomap.py index 7eb0400fb..dcf608468 100644 --- a/mne_icalabel/features/topomap.py +++ b/mne_icalabel/features/topomap.py @@ -18,8 +18,6 @@ from ..utils._docs import fill_doc if TYPE_CHECKING: - from typing import Union - from mne import Info from mne.preprocessing import ICA from numpy.typing import NDArray @@ -31,7 +29,7 @@ def get_topomaps( picks=None, res: int = 64, image_interp: str = _INTERPOLATION_DEFAULT, # 'cubic' - border: Union[float, str] = _BORDER_DEFAULT, # 'mean' + border: float | str = _BORDER_DEFAULT, # 'mean' extrapolate: str = _EXTRAPOLATE_DEFAULT, # 'auto' -> 'head' (EEG), 'local' (MEG) ) -> dict[str, NDArray[float]]: """Generate an array of scalp topographies for the picked components. @@ -100,7 +98,7 @@ def _get_topomap_array( info: Info, res: int = 64, image_interp: str = _INTERPOLATION_DEFAULT, # 'cubic' - border: Union[float, str] = _BORDER_DEFAULT, # 'mean' + border: float | str = _BORDER_DEFAULT, # 'mean' extrapolate: str = _EXTRAPOLATE_DEFAULT, # 'auto' -> 'head' (EEG), 'local' (MEG) ) -> NDArray[float]: """Generate a scalp topographic map (n_pixels, n_pixels). diff --git a/mne_icalabel/gui/_label_components.py b/mne_icalabel/gui/_label_components.py index 6441186a7..8568f7da2 100644 --- a/mne_icalabel/gui/_label_components.py +++ b/mne_icalabel/gui/_label_components.py @@ -24,7 +24,7 @@ from mne_icalabel.config import ICA_LABELS_TO_MNE if TYPE_CHECKING: - from typing import Union + pass class ICAComponentLabeler(QMainWindow): @@ -37,9 +37,7 @@ class ICAComponentLabeler(QMainWindow): show : bool """ - def __init__( - self, inst: Union[BaseRaw, BaseEpochs], ica: ICA, show: bool = True - ) -> None: + def __init__(self, inst: BaseRaw | BaseEpochs, ica: ICA, show: bool = True) -> None: ICAComponentLabeler._check_inst_ica(inst, ica) super().__init__() # initialize the QMainwindow set_browser_backend("qt") # force MNE to use the QT Browser @@ -164,7 +162,7 @@ def _load_ui(self) -> None: # - Checkers -------------------------------------------------------------- @staticmethod - def _check_inst_ica(inst: Union[BaseRaw, BaseEpochs], ica: ICA) -> None: + def _check_inst_ica(inst: BaseRaw | BaseEpochs, ica: ICA) -> None: """Check if the ICA was fitted.""" _validate_type(inst, (BaseRaw, BaseEpochs), "inst", "raw or epochs") _validate_type(ica, ICA, "ica", "ICA") @@ -176,7 +174,7 @@ def _check_inst_ica(inst: Union[BaseRaw, BaseEpochs], ica: ICA) -> None: # - Properties ------------------------------------------------------------ @property - def inst(self) -> Union[BaseRaw, BaseEpochs]: + def inst(self) -> BaseRaw | BaseEpochs: """Instance on which the ICA has been fitted.""" return self._inst diff --git a/mne_icalabel/iclabel/features.py b/mne_icalabel/iclabel/features.py index 96004b95e..e1c3b8b5a 100644 --- a/mne_icalabel/iclabel/features.py +++ b/mne_icalabel/iclabel/features.py @@ -13,12 +13,10 @@ from ._utils import _gdatav4, _mne_to_eeglab_locs, _next_power_of_2, _pol2cart if TYPE_CHECKING: - from typing import Union - from mne.preprocessing import ICA -def get_iclabel_features(inst: Union[BaseRaw, BaseEpochs], ica: ICA): +def get_iclabel_features(inst: BaseRaw | BaseEpochs, ica: ICA): """Generate the features for ICLabel neural network. Parameters @@ -140,9 +138,7 @@ def _retrieve_eeglab_icawinv( return icawinv, weights -def _compute_ica_activations( - inst: Union[BaseRaw, BaseEpochs], ica: ICA -) -> NDArray[float]: +def _compute_ica_activations(inst: BaseRaw | BaseEpochs, ica: ICA) -> NDArray[float]: """Compute the ICA activations 'icaact' variable from an MNE ICA instance. Parameters @@ -185,7 +181,7 @@ def _compute_ica_activations( # ---------------------------------------------------------------------------- def _eeg_topoplot( - inst: Union[BaseRaw, BaseEpochs], icawinv: NDArray[float], picks: list[str] + inst: BaseRaw | BaseEpochs, icawinv: NDArray[float], picks: list[str] ) -> NDArray[float]: """Topoplot feature.""" ncomp = icawinv.shape[-1] @@ -258,10 +254,10 @@ def _topoplotFast( # ---------------------------------------------------------------------------- def _eeg_rpsd( - inst: Union[BaseRaw, BaseEpochs], ica: ICA, icaact: NDArray[float] + inst: BaseRaw | BaseEpochs, ica: ICA, icaact: NDArray[float] ) -> NDArray[float]: """PSD feature.""" - assert isinstance(inst, (BaseRaw, BaseEpochs)) # sanity-check + assert isinstance(inst, (BaseRaw | BaseEpochs)) # sanity-check constants = _eeg_rpsd_constants(inst, ica) psd = _eeg_rpsd_compute_psdmed(inst, icaact, *constants) psd = _eeg_rpsd_format(psd) @@ -269,7 +265,7 @@ def _eeg_rpsd( def _eeg_rpsd_constants( - inst: Union[BaseRaw, BaseEpochs], + inst: BaseRaw | BaseEpochs, ica: ICA, ) -> tuple[int, int, int, int, NDArray[int], NDArray[float], NDArray[int]]: """Compute the constants before ``randperm`` is used to compute the subset.""" @@ -314,7 +310,7 @@ def _eeg_rpsd_constants( def _eeg_rpsd_compute_psdmed( - inst: Union[BaseRaw, BaseEpochs], + inst: BaseRaw | BaseEpochs, icaact: NDArray[float], ncomp: int, nfreqs: int, @@ -539,7 +535,7 @@ def _eeg_autocorr_fftw( return np.real(resamp).astype(np.float32) -def _resample(ac: NDArray[float], fs: Union[int, float]) -> NDArray[float]: +def _resample(ac: NDArray[float], fs: int | float) -> NDArray[float]: """Resample the autocorrelation feature. The comment in EEGLAB is: diff --git a/mne_icalabel/iclabel/label_components.py b/mne_icalabel/iclabel/label_components.py index bf8e2797d..2a3b3866c 100644 --- a/mne_icalabel/iclabel/label_components.py +++ b/mne_icalabel/iclabel/label_components.py @@ -1,5 +1,3 @@ -from typing import Optional, Union - import numpy as np from mne import BaseEpochs from mne.io import BaseRaw @@ -10,10 +8,10 @@ def iclabel_label_components( - inst: Union[BaseRaw, BaseEpochs], + inst: BaseRaw | BaseEpochs, ica: ICA, inplace: bool = True, - backend: Optional[str] = None, + backend: str | None = None, ): """Label the provided ICA components with the ICLabel neural network. diff --git a/mne_icalabel/iclabel/network/__init__.py b/mne_icalabel/iclabel/network/__init__.py index 661882e9a..fd16ed812 100644 --- a/mne_icalabel/iclabel/network/__init__.py +++ b/mne_icalabel/iclabel/network/__init__.py @@ -16,7 +16,7 @@ def run_iclabel( images: ArrayLike, psds: ArrayLike, autocorr: ArrayLike, - backend: Optional[str] = "pytorch", + backend: str | None = "pytorch", ) -> NDArray: """Run the ICLabel network on the provided set of features. diff --git a/mne_icalabel/iclabel/tests/test_utils.py b/mne_icalabel/iclabel/tests/test_utils.py index a00513f86..ea99224e3 100644 --- a/mne_icalabel/iclabel/tests/test_utils.py +++ b/mne_icalabel/iclabel/tests/test_utils.py @@ -83,6 +83,6 @@ def test_next_power_of_2(): """Test that next_power_of_2 works as intended.""" x = [0, 10, 200, 400] expected = [1, 16, 256, 512] - for k, exp in zip(x, expected): + for k, exp in zip(x, expected, strict=False): val = _next_power_of_2(k) assert exp == val diff --git a/mne_icalabel/label_components.py b/mne_icalabel/label_components.py index 66d797a5e..5d735159c 100644 --- a/mne_icalabel/label_components.py +++ b/mne_icalabel/label_components.py @@ -11,14 +11,12 @@ from .utils._checks import _validate_inst_and_ica if TYPE_CHECKING: - from typing import Union - from mne import BaseEpochs from mne.io import BaseRaw from mne.preprocessing import ICA -def label_components(inst: Union[BaseRaw, BaseEpochs], ica: ICA, method: str): +def label_components(inst: BaseRaw | BaseEpochs, ica: ICA, method: str): """Automatically label the ICA components with the selected method. Parameters diff --git a/mne_icalabel/utils/_checks.py b/mne_icalabel/utils/_checks.py index b63d58685..c3d954429 100644 --- a/mne_icalabel/utils/_checks.py +++ b/mne_icalabel/utils/_checks.py @@ -1,12 +1,10 @@ -from typing import Union - from mne import BaseEpochs from mne.io import BaseRaw from mne.preprocessing import ICA from mne.utils import _validate_type -def _validate_inst_and_ica(inst: Union[BaseRaw, BaseEpochs], ica: ICA): +def _validate_inst_and_ica(inst: BaseRaw | BaseEpochs, ica: ICA): """Make sure that the provided instance and ICA are valid.""" _validate_type(inst, (BaseRaw, BaseEpochs), "inst", "Raw or Epochs") _validate_ica(ica) diff --git a/mne_icalabel/utils/_docs.py b/mne_icalabel/utils/_docs.py index b0c3a9cfc..9217ebd5b 100644 --- a/mne_icalabel/utils/_docs.py +++ b/mne_icalabel/utils/_docs.py @@ -13,7 +13,8 @@ from mne.utils.docs import docdict as docdict_mne if TYPE_CHECKING: - from typing import Any, Callable + from collections.abc import Callable + from typing import Any # -- Documentation dictionary ---------------------------------------------------------- docdict: dict[str, str] = {} diff --git a/mne_icalabel/utils/_docs.pyi b/mne_icalabel/utils/_docs.pyi index 34dd542a5..0128d0113 100644 --- a/mne_icalabel/utils/_docs.pyi +++ b/mne_icalabel/utils/_docs.pyi @@ -1,4 +1,5 @@ -from typing import Any, Callable +from collections.abc import Callable +from typing import Any docdict: dict[str, str] _KEYS_MNE: tuple[str, ...] diff --git a/mne_icalabel/utils/_imports.py b/mne_icalabel/utils/_imports.py index 68d267cca..e095280cf 100644 --- a/mne_icalabel/utils/_imports.py +++ b/mne_icalabel/utils/_imports.py @@ -10,7 +10,6 @@ if TYPE_CHECKING: from types import ModuleType - from typing import Optional # A mapping from import name to package name (on PyPI) when the package name # is different. @@ -29,7 +28,7 @@ def import_optional_dependency( name: str, extra: str = "", raise_error: bool = True, -) -> Optional[ModuleType]: +) -> ModuleType | None: """Import an optional dependency. By default, if a dependency is missing an ImportError with a nice message will be diff --git a/mne_icalabel/utils/_tests.py b/mne_icalabel/utils/_tests.py index eed8f7283..2c349264a 100644 --- a/mne_icalabel/utils/_tests.py +++ b/mne_icalabel/utils/_tests.py @@ -6,7 +6,7 @@ import pytest if TYPE_CHECKING: - from typing import Callable + from collections.abc import Callable def requires_module(name: str): # pragma: no cover diff --git a/mne_icalabel/utils/config.py b/mne_icalabel/utils/config.py index 68e8c1875..11089172c 100644 --- a/mne_icalabel/utils/config.py +++ b/mne_icalabel/utils/config.py @@ -11,10 +11,11 @@ from packaging.requirements import Requirement if TYPE_CHECKING: - from typing import IO, Callable, Optional + from collections.abc import Callable + from typing import IO -def sys_info(fid: Optional[IO] = None, developer: bool = False): +def sys_info(fid: IO | None = None, developer: bool = False): """Print the system information for debugging. Parameters @@ -134,7 +135,7 @@ def _list_dependencies_info( @lru_cache(maxsize=1) -def _get_gpu_info() -> tuple[Optional[str], Optional[str]]: +def _get_gpu_info() -> tuple[str | None, str | None]: """Get the GPU information.""" try: from pyvista import GPUInfo diff --git a/mne_icalabel/utils/config.pyi b/mne_icalabel/utils/config.pyi index e694a8ed4..fc04a7d6b 100644 --- a/mne_icalabel/utils/config.pyi +++ b/mne_icalabel/utils/config.pyi @@ -1,4 +1,5 @@ -from typing import IO, Callable +from collections.abc import Callable +from typing import IO from packaging.requirements import Requirement diff --git a/pyproject.toml b/pyproject.toml index 2fa23b309..21bc91063 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ classifiers = [ 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.13', 'Topic :: Scientific/Engineering', 'Topic :: Software Development', ] @@ -42,7 +42,7 @@ maintainers = [ ] name = 'mne-icalabel' readme = 'README.md' -requires-python = '~=3.9' +requires-python = '~=3.10' version = "0.8.0.dev0" [project.optional-dependencies] @@ -171,7 +171,6 @@ minversion = '8.0' [tool.ruff] extend-exclude = [] line-length = 88 -target-version = 'py39' [tool.ruff.format] docstring-code-format = true @@ -186,8 +185,6 @@ select = ['A', 'B', 'D', 'E', 'F', 'G', 'I', 'LOG', 'NPY', 'PIE', 'PT', 'T20', ' 'D100', # 'Missing docstring in public module' 'D104', # 'Missing docstring in public package' 'D107', # 'Missing docstring in __init__' - 'UP007', # 'Use `X | Y` for type annotations', requires python 3.10 - 'UP038', # 'Use X | Y in {} call instead of (X, Y)', requires python 3.10 ] '*.pyi' = ['E501'] '__init__.py' = ['F401'] diff --git a/tools/stubgen.py b/tools/stubgen.py index a24e3e747..a5956368e 100644 --- a/tools/stubgen.py +++ b/tools/stubgen.py @@ -41,7 +41,7 @@ objects = [ node for node in module_ast.body - if isinstance(node, (ast.ClassDef, ast.FunctionDef)) + if isinstance(node, (ast.ClassDef | ast.FunctionDef)) ] for node in objects: docstring = getattr(module, node.name).__doc__