content: [build-system]
  build-backend = "hatchling.build"
  requires = ["hatch-vcs", "hatchling"]
  
  [project]
  authors = [
    {email = "alexandre.gramfort@inria.fr", name = "Alexandre Gramfort"},
  ]
  classifiers = [
    "Intended Audience :: Developers",
    "Intended Audience :: Science/Research",
    "License :: OSI Approved",
    "Operating System :: MacOS",
    "Operating System :: Microsoft :: Windows",
    "Operating System :: POSIX",
    "Operating System :: Unix",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python",
    "Topic :: Scientific/Engineering",
    "Topic :: Software Development",
  ]
  dependencies = [
    "decorator",
    "jinja2",
    "lazy_loader >= 0.3",
    "matplotlib >= 3.8",  # released: 2023/09/15
    "numpy >= 1.26,<3",  # released: 2023/09/16
    "packaging",
    "pooch >= 1.5",
    "scipy >= 1.11",  # released: 2023/06/25
    "tqdm",
  ]
  description = "MNE-Python project for MEG and EEG data analysis."
  dynamic = ["version"]
  keywords = [
    "brain",
    "ECoG",
    "EEG",
    "fNIRS",
    "MEG",
    "neuroimaging",
    "neuroscience",
  ]
  license = "BSD-3-Clause"
  license-files = ["LICENSE"]
  maintainers = [{email = "dan@mccloy.info", name = "Dan McCloy"}]
  name = "mne"
  readme = {content-type = "text/x-rst", file = "README.rst"}
  requires-python = ">= 3.10"
  scripts = {mne = "mne.commands.utils:main"}
  
  [project.optional-dependencies]
  # Leave this one here for backward-compat
  data = []
  dev = ["mne[doc,test]", "rcssmin"]
  # Dependencies for building the documentation
  doc = [
    "graphviz",
    "intersphinx_registry >= 0.2405.27",
    "ipython != 8.7.0",  # also in "full-no-qt" and "test"
    "memory_profiler",
    "mne-bids",
    "mne-connectivity",
    "mne-gui-addons",
    "neo",
    "numpydoc",
    "openneuro-py",
    "psutil",
    "pydata_sphinx_theme >= 0.15.2",
    "pygments >= 2.13",
    "pytest",
    "pyxdf",
    "pyzmq != 24.0.0",
    "seaborn != 0.11.2",
    "selenium >= 4.27.1",
    "sphinx >= 6",
    "sphinx-design",
    "sphinx-gallery >= 0.16",
    "sphinx_copybutton",
    "sphinxcontrib-bibtex >= 2.5",
    "sphinxcontrib-towncrier >=0.5.0a0",
    "sphinxcontrib-youtube",
  ]
  full = ["mne[full-no-qt]", "PyQt6 != 6.6.0", "PyQt6-Qt6 != 6.6.0, != 6.7.0"]
  # Dependencies for full MNE-Python functionality (other than raw/epochs export)
  # We first define a variant without any Qt bindings. The "complete" variant, mne[full],
  # makes an opinionated choice and installs PyQt6.
  # We also offter two more variants: mne[full-qt6] (which is equivalent to mne[full]),
  # and mne[full-pyside6], which will install PySide6 instead of PyQt6.
  full-no-qt = [
    "antio >= 0.5.0",
    "darkdetect",
    "defusedxml",
    "dipy",
    "edfio >= 0.4.10",
    "eeglabio",
    "filelock >= 3.18.0",
    "h5py",
    "imageio >= 2.6.1",
    "imageio-ffmpeg >= 0.4.1",
    "ipyevents",
    "ipympl",
    "ipython != 8.7.0",  # for notebook backend; also in "doc" and "test"
    "ipywidgets",
    "joblib",
    "jupyter",
    "mffpy >= 0.5.7",
    "mne-qt-browser",
    "mne[hdf5]",
    "neo",
    "nibabel",
    "nilearn",
    "numba",
    "openmeeg >= 2.5.7",  # released: 2023/11/16
    "pandas >= 2.1",  # released: 2023/08/30
    "pillow",  # for `Brain.save_image` and `mne.Report`
    "pyarrow",  # only needed to avoid a deprecation warning in pandas
    "pybv",
    "pyobjc-framework-Cocoa >= 5.2.0; platform_system == 'Darwin'",
    "python-picard",
    "pyvista >= 0.32, != 0.35.2, != 0.38.0, != 0.38.1, != 0.38.2, != 0.38.3, != 0.38.4, != 0.38.5, != 0.38.6, != 0.42.0",
    "pyvistaqt >= 0.4",
    "qdarkstyle != 3.2.2",
    "qtpy",
    "scikit-learn >=1.3.0",  # released: 2023/06/30
    "sip",
    "snirf",
    "statsmodels",
    "threadpoolctl",
    "traitlets",
    "trame",
    "trame-vtk",
    "trame-vuetify",
    "vtk >= 9.2",
    "xlrd",
  ]
  full-pyqt6 = ["mne[full]"]
  full-pyside6 = ["mne[full-no-qt]", "PySide6 != 6.7.0, != 6.8.0, != 6.8.0.1, != 6.9.1"]
  # Dependencies for MNE-Python functions that use HDF5 I/O
  hdf5 = ["h5io >= 0.2.4", "pymatreader"]
  # Dependencies for running the test infrastructure
  test = [
    "codespell",
    "flaky",
    "ipython != 8.7.0",  # for testing notebook backend; also in "full-no-qt" and "doc"
    "mypy",
    "numpydoc",
    "pre-commit",
    "pytest >= 8.0",
    "pytest-cov",
    "pytest-qt",
    "pytest-timeout",
    "ruff",
    "toml-sort",
    "tomli; python_version<'3.11'",
    "twine",
    "vulture",
    "wheel",
  ]
  # Dependencies for being able to run additional tests (rare/CIs/advanced devs)
  # Changes here should be reflected in the mne/utils/config.py dev dependencies section
  test_extra = [
    "edfio >= 0.4.10",
    "eeglabio",
    "imageio >= 2.6.1",
    "imageio-ffmpeg >= 0.4.1",
    "jupyter_client",
    "mne-bids",
    "mne[test]",
    "nbclient",
    "nbformat",
    "neo",
    "nitime",
    "pybv",
    "snirf",
    "sphinx-gallery",
    "statsmodels",
  ]
  
  [project.urls]
  "Bug Tracker" = "https://github.com/mne-tools/mne-python/issues/"
  Documentation = "https://mne.tools/"
  Download = "https://pypi.org/project/mne/#files"
  Forum = "https://mne.discourse.group/"
  Homepage = "https://mne.tools/"
  "Source Code" = "https://github.com/mne-tools/mne-python/"
  
  [tool.bandit.assert_used]
  skips = ["*/test_*.py"]  # assert statements are good practice with pytest
  
  [tool.changelog-bot]
  
  [tool.changelog-bot.towncrier_changelog]
  changelog_skip_label = "no-changelog-entry-needed"
  enabled = true
  verify_pr_number = true
  
  [tool.codespell]
  builtin = "clear,rare,informal,names,usage"
  ignore-words = "ignore_words.txt"
  skip = "doc/references.bib"
  
  [tool.hatch.build]
  exclude = [
    "/*.toml",
    "/*.txt",
    "/*.yaml",
    "/*.yml",
    "/.*",
    "/CITATION.cff",
    "/codemeta.json",
    "/CONTRIBUTING.md",
    "/doc",
    "/examples",
    "/ignore_words.txt",
    "/logo",
    "/Makefile",
    "/mne/**/tests",
    "/tools",
    "/tutorials",
  ]  # tracked by git, but we don't want to ship those files
  
  [tool.hatch.version]
  raw-options = {version_scheme = "release-branch-semver"}
  source = "vcs"
  
  [tool.mypy]
  # Avoid the conflict between mne/__init__.py and mne/__init__.pyi by ignoring the former
  exclude = '^mne/(beamformer|channels|commands|datasets|decoding|export|forward|gui|html_templates|inverse_sparse|io|minimum_norm|preprocessing|report|simulation|source_space|stats|time_frequency|utils|viz)?/?__init__\.py$'
  ignore_errors = true
  modules = ["mne"]
  scripts_are_modules = true
  strict = false
  
  [[tool.mypy.overrides]]
  ignore_missing_imports = true
  module = ['scipy.*']
  
  [[tool.mypy.overrides]]
  # Ignore "attr-defined" until we fix stuff like:
  # - BunchConstNamed: '"BunchConstNamed" has no attribute "FIFFB_EVOKED"'
  # - Missing __all__: 'Module "mne.io.snirf" does not explicitly export attribute "read_raw_snirf"'
  # Ignore "no-untyped-call" until we fix stuff like:
  # - 'Call to untyped function "end_block" in typed context'
  # Ignore "no-untyped-def" until we fix stuff like:
  # - 'Function is missing a type annotation'
  # Ignore "misc" until we fix stuff like:
  # - 'Cannot determine type of "_projector" in base class "ProjMixin"'
  # Ignore "assignment" until we fix stuff like:
  # - 'Incompatible types in assignment (expression has type "tuple[str, ...]", variable has type "str")'
  # Ignore "operator" until we fix stuff like:
  # - Unsupported operand types for - ("None" and "int")
  disable_error_code = [
    'assignment',
    'attr-defined',
    'misc',
    'no-untyped-call',
    'no-untyped-def',
    'operator',
  ]
  ignore_errors = false
  module = ['mne.annotations', 'mne.epochs', 'mne.evoked', 'mne.io']
  
  [tool.pytest.ini_options]
  # -r f (failed), E (error), s (skipped), x (xfail), X (xpassed), w (warnings)
  # don't put in xfail for pytest 8.0+ because then it prints the tracebacks,
  # which look like real errors
  addopts = [
    "--capture=sys",
    "--color=yes",
    "--cov-branch",
    "--cov-report=",
    "--doctest-ignore-import-errors",
    "--doctest-modules",
    "--durations=20",
    "--ignore=mne/gui/_*.py",
    "--ignore=mne/icons",
    "--ignore=mne/report/js_and_css",
    "--junit-xml=junit-results.xml",
    "--tb=short",
    "-rfEXs",
  ]
  testpaths = [
    "mne",
  ]
  
  [tool.rstcheck]
  ignore_directives = [
    "autoclass",
    "autofunction",
    "automodule",
    "autosummary",
    "bibliography",
    "card",
    "cssclass",
    "currentmodule",
    "dropdown",
    "footbibliography",
    "glossary",
    "graphviz",
    "grid",
    "highlight",
    "minigallery",
    "related-software",
    "rst-class",
    "tab-set",
    "tabularcolumns",
    "toctree",
    "towncrier-draft-entries",
  ]
  ignore_messages = "^.*(Unknown target name|Undefined substitution referenced)[^`]*$"
  ignore_roles = [
    "attr",
    "bdg-info-line",
    "bdg-primary-line",
    "class",
    "doc",
    "eq",
    "exc",
    "file",
    "footcite",
    "footcite:t",
    "func",
    "gh",
    "kbd",
    "meth",
    "mod",
    "newcontrib",
    "py:mod",
    "ref",
    "samp",
    "term",
  ]
  report_level = "WARNING"
  
  [tool.ruff]
  exclude = ["__init__.py", "constants.py", "resources.py"]
  
  [tool.ruff.lint]
  ignore = [
    "D100",  # Missing docstring in public module
    "D104",  # Missing docstring in public package
    "D413",  # Missing blank line after last section
  ]
  select = ["A", "B006", "D", "E", "F", "I", "UP", "UP031", "W"]
  
  [tool.ruff.lint.per-file-ignores]
  "examples/*/*.py" = [
    "D205",  # 1 blank line required between summary line and description
    "D400",  # First line should end with a period
  ]
  "examples/preprocessing/eeg_bridging.py" = [
    "E501",  # line too long
  ]
  "mne/__init__.pyi" = [
    "A004",  # Import *** is shadowing a Python builtin
  ]
  "mne/datasets/*/*.py" = [
    "D103",  # Missing docstring in public function
  ]
  "mne/decoding/tests/test_*.py" = [
    "E402",  # Module level import not at top of file
  ]
  "mne/utils/tests/test_docs.py" = [
    "D101",  # Missing docstring in public class
    "D410",  # Missing blank line after section
    "D411",  # Missing blank line before section
    "D414",  # Section has no content
  ]
  "tutorials/*/*.py" = [
    "D400",  # First line should end with a period
  ]
  "tutorials/time-freq/10_spectrum_class.py" = [
    "E501",  # line too long
  ]
  
  [tool.ruff.lint.pydocstyle]
  convention = "numpy"
  ignore-decorators = [
    "mne.utils.copy_doc",
    "mne.utils.copy_function_doc_to_method_doc",
    "mne.utils.deprecated",
    "property",
    "setter",
  ]
  
  [tool.tomlsort]
  all = true
  ignore_case = true
  spaces_before_inline_comment = 2
  trailing_comma_inline_array = true
  
  [tool.towncrier]
  directory = "doc/changes/dev/"
  filename = "doc/changes/dev.rst"
  issue_format = "`#{issue} <https://github.com/mne-tools/mne-python/pull/{issue}>`__"
  package = "mne"
  title_format = "{version} ({project_date})"
  
  [[tool.towncrier.type]]
  directory = "notable"
  name = "Notable changes"
  showcontent = true
  
  [[tool.towncrier.type]]
  directory = "dependency"
  name = "Dependencies"
  showcontent = true
  
  [[tool.towncrier.type]]
  directory = "bugfix"
  name = "Bugfixes"
  showcontent = true
  
  [[tool.towncrier.type]]
  directory = "apichange"
  name = "API changes by deprecation"
  showcontent = true
  
  [[tool.towncrier.type]]
  directory = "newfeature"
  name = "New features"
  showcontent = true
  
  [[tool.towncrier.type]]
  directory = "other"
  name = "Other changes"
  showcontent = true
  
  [tool.vulture]
  exclude = [
    'conftest.py',
    'constants.py',
    'mne/viz/backends/_abstract.py',
    'mne/viz/backends/_notebook.py',
    'mne/viz/backends/_qt.py',
  ]
  ignore_decorators = ['@observe']
  min_confidence = 60
  paths = ['mne', 'tools/vulture_allowlist.py']
  verbose = false
  