diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f11c346045..3e5d1f43b35 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,7 +44,7 @@ jobs: which python which pip pip install --upgrade pip setuptools wheel - pip install --upgrade --only-binary "numpy,scipy,dipy,statsmodels" -ve . -r requirements.txt -r requirements_testing.txt -r requirements_testing_extra.txt PyQt6 + pip install --upgrade --only-binary "numpy,scipy,dipy,statsmodels" -ve .[full] -r requirements_testing.txt -r requirements_testing_extra.txt PyQt6 # 3D too slow on Apple's software renderer, and numba causes us problems pip uninstall -y vtk pyvista pyvistaqt numba mkdir -p test-results diff --git a/.git_archival.txt b/.git_archival.txt new file mode 100644 index 00000000000..8fb235d7045 --- /dev/null +++ b/.git_archival.txt @@ -0,0 +1,4 @@ +node: $Format:%H$ +node-date: $Format:%cI$ +describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$ +ref-names: $Format:%D$ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..00a7b00c94e --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +.git_archival.txt export-subst diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 9e12649b5fe..00000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,92 +0,0 @@ -include *.rst -include LICENSE.txt -include SECURITY.md -include requirements.txt -include requirements_base.txt -include requirements_hdf5.txt -include requirements_testing.txt -include requirements_testing_extra.txt -include requirements_doc.txt -include mne/__init__.py - -recursive-include examples *.py -recursive-include examples *.txt -recursive-include tutorials *.py -recursive-include tutorials *.txt - -recursive-include mne *.py -recursive-include mne *.pyi -recursive-include mne/data * -recursive-include mne/icons * -recursive-include mne/data/helmets * -recursive-include mne/data/image * -recursive-include mne/data/fsaverage * -include mne/datasets/_fsaverage/root.txt -include mne/datasets/_fsaverage/bem.txt -include mne/datasets/_infant/*.txt -include mne/datasets/_phantom/*.txt -include mne/data/dataset_checksums.txt -include mne/data/eegbci_checksums.txt - -recursive-include mne/html_templates *.html.jinja - -recursive-include mne/channels/data/layouts * -recursive-include mne/channels/data/montages * -recursive-include mne/channels/data/neighbors * - -recursive-include mne/gui/help *.json - -recursive-include mne/html *.js -recursive-include mne/html *.css - -recursive-include mne/report * - -recursive-include mne/io/artemis123/resources * - -recursive-include mne mne/datasets *.csv -include mne/io/edf/gdf_encodes.txt -include mne/datasets/sleep_physionet/SHA1SUMS - -### Exclude - -recursive-exclude examples/MNE-sample-data * -recursive-exclude examples/MNE-testing-data * -recursive-exclude examples/MNE-spm-face * -recursive-exclude examples/MNE-somato-data * -recursive-exclude tools * -exclude tools -exclude Makefile -exclude .coveragerc -exclude *.yml -exclude *.yaml -exclude .git-blame-ignore-revs -exclude ignore_words.txt -exclude .mailmap -exclude codemeta.json -exclude CITATION.cff -recursive-exclude mne *.pyc - -recursive-exclude doc * -recursive-exclude logo * - -exclude CONTRIBUTING.md -exclude CODE_OF_CONDUCT.md -exclude .github -exclude .github/CONTRIBUTING.md -exclude .github/ISSUE_TEMPLATE -exclude .github/ISSUE_TEMPLATE/blank.md -exclude .github/ISSUE_TEMPLATE/bug_report.md -exclude .github/ISSUE_TEMPLATE/feature_request.md -exclude .github/PULL_REQUEST_TEMPLATE.md - -# Test files - -recursive-exclude mne/io/tests/data * -recursive-exclude mne/io/besa/tests/data * -recursive-exclude mne/io/bti/tests/data * -recursive-exclude mne/io/edf/tests/data * -recursive-exclude mne/io/kit/tests/data * -recursive-exclude mne/io/brainvision/tests/data * -recursive-exclude mne/io/egi/tests/data * -recursive-exclude mne/io/nicolet/tests/data * -recursive-exclude mne/preprocessing/tests/data * diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1b8ddc505a4..d82835b4b00 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -52,7 +52,7 @@ stages: - bash: | set -eo pipefail python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off -r requirements_base.txt -r requirements_hdf5.txt -r requirements_testing.txt + python -m pip install --progress-bar off .[hdf5] -r requirements_testing.txt python -m pip uninstall -yq pytest-qt # don't want to set up display, etc. for this pre-commit install --install-hooks displayName: Install dependencies diff --git a/doc/development/contributing.rst b/doc/development/contributing.rst index 2dbf90d306b..e78ad5ce7ed 100644 --- a/doc/development/contributing.rst +++ b/doc/development/contributing.rst @@ -304,7 +304,7 @@ be reflected the next time you open a Python interpreter and ``import mne`` Finally, we'll add a few dependencies that are not needed for running MNE-Python, but are needed for locally running our test suite:: - $ pip install -r requirements_testing.txt + $ pip install -r requirements_testing.txt -r requirements_testing_extra.txt And for building our documentation:: diff --git a/pyproject.toml b/pyproject.toml index f28204f5bca..90a7d0955fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,10 @@ [project] name = "mne" description = "MNE-Python project for MEG and EEG data analysis." -maintainers = [ +authors = [ { name = "Alexandre Gramfort", email = "alexandre.gramfort@inria.fr" }, ] +maintainers = [{ name = "Dan McCloy", email = "dan@mccloy.info" }] dynamic = ["version"] license = { text = "BSD-3-Clause" } readme = { file = "README.rst", content-type = "text/x-rst" } @@ -30,9 +31,70 @@ classifiers = [ "Operating System :: MacOS", "Programming Language :: Python :: 3", ] +scripts = { mne = "mne.commands.utils:main" } +dependencies = [ + "numpy>=1.21.2", + "scipy>=1.7.1", + "matplotlib>=3.5.0", + "tqdm", + "pooch>=1.5", + "decorator", + "packaging", + "jinja2", + "importlib_resources>=5.10.2; python_version<'3.9'", + "lazy_loader>=0.3", + "defusedxml", +] + +[project.optional-dependencies] +# requirements for full MNE-Python functionality (other than raw/epochs export) +full = [ + "h5io", + "pymatreader", + "qtpy", + "PyQt6", + "pyobjc-framework-Cocoa>=5.2.0; platform_system=='Darwin'", + "sip", + "scikit-learn", + "nibabel", + "openmeeg>=2.5.5", + "numba", + "h5py", + "pandas", + "numexpr", + "jupyter", + "python-picard", + "statsmodels", + "joblib", + "psutil", + "dipy", + "vtk", + "nilearn", + "xlrd", + "imageio>=2.6.1", + "imageio-ffmpeg>=0.4.1", + "traitlets", + "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", + "mffpy>=0.5.7", + "ipywidgets", + "ipympl", + "ipyevents", + "trame", + "trame-vtk", + "trame-vuetify", + "mne-qt-browser", + "darkdetect", + "qdarkstyle", + "threadpoolctl", +] + +# data is empty, but let's leave it here so that we don't break people's workflows who +# did `pip install mne[data]` +data = [] # here for backward-compat -[project.scripts] -mne = "mne.commands.utils:main" +# requirements for MNE-Python functions that use HDF5 I/O +hdf5 = ["h5io", "pymatreader"] [project.urls] Homepage = "https://mne.tools/" @@ -43,47 +105,14 @@ Forum = "https://mne.discourse.group/" "Source Code" = "https://github.com/mne-tools/mne-python/" [build-system] -requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2", "wheel"] -build-backend = "setuptools.build_meta" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" -[tool.setuptools_scm] -write_to = "mne/_version.py" -version_scheme = "release-branch-semver" - -[options] -zip_safe = false # the package can run out of an .egg file -include_package_data = true - -[tool.setuptools.package-data] -"mne" = [ - "data/eegbci_checksums.txt", - "data/*.sel", - "data/icos.fif.gz", - "data/coil_def*.dat", - "data/helmets/*.fif.gz", - "data/FreeSurferColorLUT.txt", - "data/image/*gif", - "data/image/*lout", - "data/fsaverage/*.fif", - "channels/data/layouts/*.lout", - "channels/data/layouts/*.lay", - "channels/data/montages/*.sfp", - "channels/data/montages/*.txt", - "channels/data/montages/*.elc", - "channels/data/neighbors/*.mat", - "datasets/sleep_physionet/SHA1SUMS", - "datasets/_fsaverage/*.txt", - "datasets/_infant/*.txt", - "datasets/_phantom/*.txt", - "html/*.js", - "html/*.css", - "html_templates/repr/*.jinja", - "html_templates/report/*.jinja", - "icons/*.svg", - "icons/*.png", - "io/artemis123/resources/*.csv", - "io/edf/gdf_encodes.txt", -] +[tool.hatch] +version.source = "vcs" +version.raw-options = { version_scheme = "release-branch-semver" } +build.hooks.vcs.version-file = "mne/_version.py" +build.exclude = ["/.*", "/*.yml", "/*.yaml", "/*.toml", "/*.txt"] [tool.codespell] ignore-words = "ignore_words.txt" @@ -144,13 +173,44 @@ skips = ["*/test_*.py"] # assert statements are good practice with pytest [tool.rstcheck] report_level = "WARNING" ignore_roles = [ - "func", "class", "term", "ref", "doc", "gh", "file", "samp", "meth", "mod", "kbd", - "newcontrib", "footcite", "footcite:t", "eq", "py:mod", "attr", "py:class", "exc", + "func", + "class", + "term", + "ref", + "doc", + "gh", + "file", + "samp", + "meth", + "mod", + "kbd", + "newcontrib", + "footcite", + "footcite:t", + "eq", + "py:mod", + "attr", + "py:class", + "exc", ] ignore_directives = [ - "rst-class", "tab-set", "grid", "toctree", "footbibliography", "autosummary", - "currentmodule", "automodule", "cssclass", "tabularcolumns", "minigallery", - "autoclass", "highlight", "dropdown", "graphviz", "glossary", "autofunction", + "rst-class", + "tab-set", + "grid", + "toctree", + "footbibliography", + "autosummary", + "currentmodule", + "automodule", + "cssclass", + "tabularcolumns", + "minigallery", + "autoclass", + "highlight", + "dropdown", + "graphviz", + "glossary", + "autofunction", "bibliography", ] ignore_messages = "^.*(Unknown target name|Undefined substitution referenced)[^`]*$" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 90944200247..00000000000 --- a/requirements.txt +++ /dev/null @@ -1,47 +0,0 @@ -# requirements for full MNE-Python functionality (other than raw/epochs export) -numpy>=1.15.4 -scipy>=1.7.1 -matplotlib>=3.5.0 -tqdm -pooch>=1.5 -decorator -h5io -packaging -pymatreader -qtpy -PyQt6 -pyobjc-framework-Cocoa>=5.2.0; platform_system=="Darwin" -sip -scikit-learn -nibabel -openmeeg>=2.5.5 -numba -h5py -jinja2 -pandas -numexpr -jupyter -python-picard -statsmodels -joblib -psutil -dipy -vtk -nilearn -xlrd -imageio>=2.6.1 -imageio-ffmpeg>=0.4.1 -traitlets -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 -mffpy>=0.5.7 -ipywidgets -ipympl -ipyevents -trame -trame-vtk -trame-vuetify -mne-qt-browser -darkdetect -qdarkstyle -threadpoolctl diff --git a/requirements_base.txt b/requirements_base.txt deleted file mode 100644 index 2e6ba6e6c80..00000000000 --- a/requirements_base.txt +++ /dev/null @@ -1,12 +0,0 @@ -# requirements for basic MNE-Python functionality -numpy>=1.21.2 -scipy>=1.7.1 -matplotlib>=3.5.0 -tqdm -pooch>=1.5 -decorator -packaging -jinja2 -importlib_resources>=5.10.2; python_version<'3.9' -lazy_loader>=0.3 -defusedxml diff --git a/requirements_hdf5.txt b/requirements_hdf5.txt deleted file mode 100644 index 6d60bf93dab..00000000000 --- a/requirements_hdf5.txt +++ /dev/null @@ -1,3 +0,0 @@ -# requirements for MNE-Python functions that use HDF5 I/O -h5io -pymatreader diff --git a/setup.py b/setup.py deleted file mode 100644 index d3422b58a6a..00000000000 --- a/setup.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python - -# Copyright (C) 2011-2020 Alexandre Gramfort -# - -import os -import os.path as op - -from setuptools import setup - - -def parse_requirements_file(fname): - requirements = list() - with open(fname, "r") as fid: - for line in fid: - req = line.strip() - if req.startswith("#"): - continue - # strip end-of-line comments - req = req.split("#", maxsplit=1)[0].strip() - requirements.append(req) - return requirements - - -def package_tree(pkgroot): - """Get the submodule list.""" - # Adapted from VisPy - path = op.dirname(__file__) - subdirs = [ - op.relpath(i[0], path).replace(op.sep, ".") - for i in os.walk(op.join(path, pkgroot)) - if "__init__.py" in i[2] - ] - return sorted(subdirs) - - -if __name__ == "__main__": - if op.exists("MANIFEST"): - os.remove("MANIFEST") - - # data_dependencies is empty, but let's leave them so that we don't break - # people's workflows who did `pip install mne[data]` - install_requires = parse_requirements_file("requirements_base.txt") - data_requires = [] - hdf5_requires = parse_requirements_file("requirements_hdf5.txt") - test_requires = parse_requirements_file( - "requirements_testing.txt" - ) + parse_requirements_file("requirements_testing_extra.txt") - setup( - install_requires=install_requires, - extras_require={ - "data": data_requires, - "hdf5": hdf5_requires, - "test": test_requires, - }, - packages=package_tree("mne"), - )