From 9a039eb5709324245c2dcc0ea620c5f8e1cd45a0 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Fri, 13 Dec 2024 20:09:39 -0500 Subject: [PATCH 01/14] rf: Upgrade to acres.Loader --- pyproject.toml | 1 + sdcflows/data/__init__.py | 171 +------------------------------------- 2 files changed, 3 insertions(+), 169 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fa54d89b70..fc11e40b84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ classifiers = [ license = "Apache-2.0" requires-python = ">=3.9" dependencies = [ + "acres >= 0.2.0", "attrs >= 20.1.0", "nibabel >=3.1.0", "nipype >=1.8.5,<2.0", diff --git a/sdcflows/data/__init__.py b/sdcflows/data/__init__.py index 99e82112f3..041c9366ab 100644 --- a/sdcflows/data/__init__.py +++ b/sdcflows/data/__init__.py @@ -10,173 +10,6 @@ .. autoclass:: Loader """ -from __future__ import annotations +from acres import Loader -import atexit -import os -from contextlib import AbstractContextManager, ExitStack -from functools import cached_property -from pathlib import Path -from types import ModuleType -from typing import Union - -try: - from functools import cache -except ImportError: # PY38 - from functools import lru_cache as cache - -try: # Prefer backport to leave consistency to dependency spec - from importlib_resources import as_file, files -except ImportError: - from importlib.resources import as_file, files # type: ignore - -try: # Prefer stdlib so Sphinx can link to authoritative documentation - from importlib.resources.abc import Traversable -except ImportError: - from importlib_resources.abc import Traversable - -__all__ = ["load"] - - -class Loader: - """A loader for package files relative to a module - - This class wraps :mod:`importlib.resources` to provide a getter - function with an interpreter-lifetime scope. For typical packages - it simply passes through filesystem paths as :class:`~pathlib.Path` - objects. For zipped distributions, it will unpack the files into - a temporary directory that is cleaned up on interpreter exit. - - This loader accepts a fully-qualified module name or a module - object. - - Expected usage:: - - '''Data package - - .. autofunction:: load_data - - .. automethod:: load_data.readable - - .. automethod:: load_data.as_path - - .. automethod:: load_data.cached - ''' - - from sdcflows.data import Loader - - load_data = Loader(__package__) - - :class:`~Loader` objects implement the :func:`callable` interface - and generate a docstring, and are intended to be treated and documented - as functions. - - For greater flexibility and improved readability over the ``importlib.resources`` - interface, explicit methods are provided to access resources. - - +---------------+----------------+------------------+ - | On-filesystem | Lifetime | Method | - +---------------+----------------+------------------+ - | `True` | Interpreter | :meth:`cached` | - +---------------+----------------+------------------+ - | `True` | `with` context | :meth:`as_path` | - +---------------+----------------+------------------+ - | `False` | n/a | :meth:`readable` | - +---------------+----------------+------------------+ - - It is also possible to use ``Loader`` directly:: - - from sdcflows.data import Loader - - Loader(other_package).readable('data/resource.ext').read_text() - - with Loader(other_package).as_path('data') as pkgdata: - # Call function that requires full Path implementation - func(pkgdata) - - # contrast to - - from importlib_resources import files, as_file - - files(other_package).joinpath('data/resource.ext').read_text() - - with as_file(files(other_package) / 'data') as pkgdata: - func(pkgdata) - - .. automethod:: readable - - .. automethod:: as_path - - .. automethod:: cached - """ - - def __init__(self, anchor: Union[str, ModuleType]): - self._anchor = anchor - self.files = files(anchor) - self.exit_stack = ExitStack() - atexit.register(self.exit_stack.close) - # Allow class to have a different docstring from instances - self.__doc__ = self._doc - - @cached_property - def _doc(self): - """Construct docstring for instances - - Lists the public top-level paths inside the location, where - non-public means has a `.` or `_` prefix or is a 'tests' - directory. - """ - top_level = sorted( - os.path.relpath(p, self.files) + "/"[: p.is_dir()] - for p in self.files.iterdir() - if p.name[0] not in (".", "_") and p.name != "tests" - ) - doclines = [ - f"Load package files relative to ``{self._anchor}``.", - "", - "This package contains the following (top-level) files/directories:", - "", - *(f"* ``{path}``" for path in top_level), - ] - - return "\n".join(doclines) - - def readable(self, *segments) -> Traversable: - """Provide read access to a resource through a Path-like interface. - - This file may or may not exist on the filesystem, and may be - efficiently used for read operations, including directory traversal. - - This result is not cached or copied to the filesystem in cases where - that would be necessary. - """ - return self.files.joinpath(*segments) - - def as_path(self, *segments) -> AbstractContextManager[Path]: - """Ensure data is available as a :class:`~pathlib.Path`. - - This method generates a context manager that yields a Path when - entered. - - This result is not cached, and any temporary files that are created - are deleted when the context is exited. - """ - return as_file(self.files.joinpath(*segments)) - - @cache - def cached(self, *segments) -> Path: - """Ensure data is available as a :class:`~pathlib.Path`. - - Any temporary files that are created remain available throughout - the duration of the program, and are deleted when Python exits. - - Results are cached so that multiple calls do not unpack the same - data multiple times, but the cache is sensitive to the specific - argument(s) passed. - """ - return self.exit_stack.enter_context(as_file(self.files.joinpath(*segments))) - - __call__ = cached - - -load = Loader(__package__) +load = Loader(__spec__.name) From 3ab0a45259b4aacbf3d9ef2b61f3da3b6638adb9 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Fri, 13 Dec 2024 20:13:37 -0500 Subject: [PATCH 02/14] chore(deps): Update minimum dependencies --- pyproject.toml | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fc11e40b84..d940ed1654 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,17 +23,16 @@ requires-python = ">=3.9" dependencies = [ "acres >= 0.2.0", "attrs >= 20.1.0", - "nibabel >=3.1.0", - "nipype >=1.8.5,<2.0", - "traits <6.4", + "nibabel >= 3.0", + "nipype >= 1.8.5", "migas >= 0.4.0", "niworkflows >= 1.7.0", - "nitransforms >= 23.0.1", - "numpy >= 1.21.0", + "nitransforms >= 24.1.0", + "numpy >= 1.22", "pybids >= 0.16.4", "scikit-image >= 0.18", "scipy >= 1.8.1", - "templateflow", + "templateflow >= 23.1", "toml", ] dynamic = ["version"] @@ -50,22 +49,13 @@ doc = [ "importlib_resources", "ipykernel", "ipython", - "matplotlib >= 2.2.0", "nbsphinx", - "nibabel", - "nipype >= 1.5.1", - "niworkflows >= 1.10.0", - "numpy", - "packaging", "pandoc", "pydot >= 1.2.3", "pydotplus", - "scipy", "sphinx >= 7.2.2", "sphinx-argparse", "sphinxcontrib-apidoc", - "templateflow", - "traits < 6.4" ] mem = [ @@ -80,11 +70,11 @@ dev = [ ] test = [ - "coverage", - "pytest", - "pytest-cov", + "coverage[toml] >=5.2.1", + "pytest >= 6", + "pytest-cov >= 2.11", "pytest-env", - "pytest-xdist" + "pytest-xdist >= 2.5", ] # Aliases From 087d867cecc07cf96a47f33c3cd2f02fd2d2a8fc Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Fri, 13 Dec 2024 21:01:34 -0500 Subject: [PATCH 03/14] chore: Add tox.ini, update pytest config --- pyproject.toml | 17 ++++++- tox.ini | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tox.ini diff --git a/pyproject.toml b/pyproject.toml index d940ed1654..7d32087383 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -150,8 +150,22 @@ per-file-ignores = [ ] [tool.pytest.ini_options] +minversion = "6" +testpaths = ["sdcflows"] +log_cli_level = "INFO" +xfail_strict = true norecursedirs = [".git"] -addopts = "-svx --doctest-modules --strict-markers" +addopts = [ + "-svx", + "-ra", + "--strict-config", + "--strict-markers", + "--doctest-modules", + # Config pytest-cov + "--cov=sdcflows", + "--cov-report=xml", + "--cov-config=pyproject.toml", +] doctest_optionflags = "ALLOW_UNICODE NORMALIZE_WHITESPACE ELLIPSIS" env = "PYTHONHASHSEED=0" filterwarnings = ["ignore::DeprecationWarning"] @@ -164,7 +178,6 @@ markers = [ [tool.coverage.run] branch = true -concurrency = 'multiprocessing' omit = [ '*/tests/*', '*/__init__.py', diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000..a5376611f7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,127 @@ +[tox] +requires = + tox>=4 + tox-uv +envlist = + py3{9,10,11,12,13}-latest + py39-min + py3{11,12,13}-pre + style + spellcheck +skip_missing_interpreters = true + +# Configuration that allows us to split tests across GitHub runners effectively +[gh-actions] +python = + 3.9: py39 + 3.10: py310 + 3.11: py311 + 3.12: py312 + 3.13: py313 + +[gh-actions:env] +DEPENDS = + min: min + latest: latest + pre: pre + +[testenv] +description = Pytest with coverage +labels = test +pip_pre = + pre: true +pass_env = + TEMPLATEFLOW_HOME + # Freesurfer variables searched for + FREESURFER_HOME + SUBJECTS_DIR + FS_LICENSE + # CI variables + TEST_DATA_HOME + TEST_OUTPUT_DIR + TEST_WORK_DIR + FMRIPREP_REGRESSION_SOURCE + CACHED_WORK_DIRECTORY + # CircleCI-specific + CIRCLE_NPROCS + SAVE_CIRCLE_ARTIFACTS + # getpass.getuser() sources for Windows: + LOGNAME + USER + LNAME + USERNAME + # Pass user color preferences through + PY_COLORS + FORCE_COLOR + NO_COLOR + CLICOLOR + CLICOLOR_FORCE + PYTHON_GIL +deps = + # Waiting on a release + py313: traits @ git+https://github.com/enthought/traits.git@10954eb +extras = tests +setenv = + pre: PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + pre: UV_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple +uv_resolution = + min: lowest-direct + +commands = + pytest --durations=20 --durations-min=1.0 --cov-report term-missing {posargs:-n auto} + +[testenv:style] +description = Check our style guide +labels = check +deps = + ruff +skip_install = true +commands = + ruff check --diff + ruff format --diff + +[testenv:style-fix] +description = Auto-apply style guide to the extent possible +labels = pre-release +deps = + ruff +skip_install = true +commands = + ruff check --fix + ruff format + ruff check --select ISC001 + +[testenv:spellcheck] +description = Check spelling +labels = check +deps = + codespell[toml] +skip_install = true +commands = + codespell . {posargs} + +[testenv:build{,-strict}] +labels = + check + pre-release +deps = + build + twine +skip_install = true +set_env = + # Ignore specific known warnings: + # https://github.com/pypa/pip/issues/11684 + # https://github.com/pypa/pip/issues/12243 + strict: PYTHONWARNINGS=error,once:pkg_resources is deprecated as an API.:DeprecationWarning:pip._internal.metadata.importlib._envs,once:Unimplemented abstract methods {'locate_file'}:DeprecationWarning:pip._internal.metadata.importlib._dists +commands = + python -m build + python -m twine check dist/* + +[testenv:publish] +depends = build +labels = release +deps = + twine +skip_install = true +commands = + python -m twine upload dist/* From 32dfc7479230e8df3a05bedd5e4ce8dd80fe4dfa Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 16:05:30 -0500 Subject: [PATCH 04/14] chore(ci): Switch to using tox-uv --- .github/workflows/build-test-publish.yml | 36 +++++++++++++++--------- tox.ini | 17 ++++++++--- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index d3d5a03551..f3e6eff2a9 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -49,15 +49,22 @@ jobs: AFNI_IMSAVE_WARNINGS: NO AFNI_TTATLAS_DATASET: /opt/afni/atlases AFNI_PLUGINPATH: /opt/afni/plugins + MARKS: ${{ matrix.marks }} + DEPENDS: ${{ matrix.dependencies }} strategy: - max-parallel: 6 matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] - marks: ["not slow"] + dependencies: ["latest", "pre"] + marks: ["fast"] include: - python-version: "3.9" - marks: "slow and not veryslow" + dependencies: "min" + marks: "fast" + - python-version: "3.9" + dependencies: "latest" + marks: "slow" - python-version: "3.12" + dependencies: "latest" marks: "veryslow" steps: @@ -94,6 +101,8 @@ jobs: run: | git config --global user.name 'NiPreps Bot' git config --global user.email 'nipreps@gmail.com' + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v4 - name: Set up Python ${{ matrix.python-version }} uses: conda-incubator/setup-miniconda@v3 with: @@ -114,8 +123,9 @@ jobs: python-${{ matrix.python-version }}-${{ env.CACHE_NUM }} - name: Install DataLad run: | - conda install git-annex=*=alldep* pip - pip install datalad datalad-osf + conda install git-annex=*=alldep* + uv tool install datalad --with=datalad-next --with=datalad-osf + uv tool install datalad-osf --with=datalad-next - name: Install fsl and ANTs run: | conda install fsl-fugue fsl-topup ants @@ -198,18 +208,16 @@ jobs: mkdir -p $( dirname $FS_LICENSE ) echo "b2VzdGViYW5Ac3RhbmZvcmQuZWR1CjMwNzU2CiAqQ1MzYkJ5VXMxdTVNCiBGU2kvUGJsejJxR1V3Cg==" | base64 -d > $FS_LICENSE - - name: Run pytest with coverage + - name: Install tox run: | - export PATH=${AFNI_HOME}:$PATH - export FSLDIR=${CONDA_PREFIX} - pytest -v --cov sdcflows --cov-report xml:cov.xml --doctest-modules -n auto sdcflows \ - --durations=20 --durations-min=10 -m "$MARKS" - env: - MARKS: ${{ matrix.marks }} + uv tool install tox --with=tox-uv --with=tox-gh-actions + - name: Show tox config + run: tox c + - name: Run tox + run: tox -v --exit-and-dump-after 1200 - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 with: - file: cov.xml token: ${{ secrets.CODECOV_TOKEN }} if: ${{ always() }} diff --git a/tox.ini b/tox.ini index a5376611f7..0c54dc5b94 100644 --- a/tox.ini +++ b/tox.ini @@ -3,9 +3,9 @@ requires = tox>=4 tox-uv envlist = - py3{9,10,11,12,13}-latest - py39-min - py3{11,12,13}-pre + py3{9,10,11,12,13}-latest-{fast,slow,veryslow} + py39-min-fast + py3{11,12,13}-pre-{fast,slow,veryslow} style spellcheck skip_missing_interpreters = true @@ -25,6 +25,11 @@ DEPENDS = latest: latest pre: pre +MARKS = + fast: fast + slow: slow + veryslow: veryslow + [testenv] description = Pytest with coverage labels = test @@ -68,7 +73,11 @@ uv_resolution = min: lowest-direct commands = - pytest --durations=20 --durations-min=1.0 --cov-report term-missing {posargs:-n auto} + pytest --durations=20 --durations-min=1.0 --cov-report term-missing \ + fast: -m "not slow" \ + slow: -m "slow and not veryslow" \ + veryslow: -m "veryslow" \ + {posargs:-n auto} [testenv:style] description = Check our style guide From 09722e9559519aed686e19a48a1d849c34ac4cd8 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 16:21:08 -0500 Subject: [PATCH 05/14] chore(deps): Minimum version for toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7d32087383..d0d73f8712 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ "scikit-image >= 0.18", "scipy >= 1.8.1", "templateflow >= 23.1", - "toml", + "toml >= 0.10", ] dynamic = ["version"] From 4abb75592b88ebfa098b8c99076d888bcfc9a0ae Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 16:30:41 -0500 Subject: [PATCH 06/14] chore(tox): Pass in variables set by CI --- tox.ini | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tox.ini b/tox.ini index 0c54dc5b94..5faa0e7e23 100644 --- a/tox.ini +++ b/tox.ini @@ -41,6 +41,15 @@ pass_env = FREESURFER_HOME SUBJECTS_DIR FS_LICENSE + # FSL + FSLOUTPUTTYPE + FSLMULTIFILEQUIT + # AFNI + AFNI_HOME + AFNI_MODELPATH + AFNI_IMSAVE_WARNINGS + AFNI_TTATLAS_DATASET + AFNI_PLUGINPATH # CI variables TEST_DATA_HOME TEST_OUTPUT_DIR From 9c959575fc86486b51c5ba5ca021c83f85633b2b Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 16:30:53 -0500 Subject: [PATCH 07/14] chore(ci): Disable fail-fast --- .github/workflows/build-test-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index f3e6eff2a9..f345725a99 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -52,6 +52,7 @@ jobs: MARKS: ${{ matrix.marks }} DEPENDS: ${{ matrix.dependencies }} strategy: + fail-fast: false matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] dependencies: ["latest", "pre"] From 233e0f816cc5b98269ebf4c13ad8ba2fe4caed75 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 16:46:07 -0500 Subject: [PATCH 08/14] chore(ci): Show contents of AFNI_HOME, ensure it is on PATH --- .github/workflows/build-test-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index f345725a99..374d692f0c 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -97,6 +97,8 @@ jobs: curl -O https://afni.nimh.nih.gov/pub/dist/bin/misc/@update.afni.binaries && \ tcsh @update.afni.binaries -package linux_ubuntu_16_64 -bindir ${AFNI_HOME} fi + ls -l ${AFNI_HOME} + echo "PATH=${AFNI_HOME}:$PATH" | tee -a $GITHUB_ENV - name: Git settings (pacify DataLad) run: | From 3513638bfe292722c3a4eadcea487e2ffa5b76b0 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 21:53:26 -0500 Subject: [PATCH 09/14] chore(ci): Drop pre-release tests for out-of-SPEC0 Python --- .github/workflows/build-test-publish.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 374d692f0c..a1bb2b45d2 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -67,6 +67,11 @@ jobs: - python-version: "3.12" dependencies: "latest" marks: "veryslow" + exclude: + - python-version: "3.9" + dependencies: "pre" + - python-version: "3.10" + dependencies: "pre" steps: - uses: actions/cache@v4 From ae622c8e969715f9223c66dd0eb9dbca04e64fe1 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 21:53:56 -0500 Subject: [PATCH 10/14] chore: Test on py313, set UV variables appropriately --- .github/workflows/build-test-publish.yml | 2 +- tox.ini | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index a1bb2b45d2..f2b8826c26 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] dependencies: ["latest", "pre"] marks: ["fast"] include: diff --git a/tox.ini b/tox.ini index 5faa0e7e23..77d4df3b13 100644 --- a/tox.ini +++ b/tox.ini @@ -77,7 +77,8 @@ deps = extras = tests setenv = pre: PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - pre: UV_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + pre: UV_INDEX=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + pre: UV_INDEX_STRATEGY=unsafe-best-match uv_resolution = min: lowest-direct From 4b309fad2c0c119bbac277504af89c9fc9e965db Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 21:55:15 -0500 Subject: [PATCH 11/14] fix: Drop deprecated TraitDictAnys --- sdcflows/interfaces/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdcflows/interfaces/utils.py b/sdcflows/interfaces/utils.py index 6696c786d7..a50873737e 100644 --- a/sdcflows/interfaces/utils.py +++ b/sdcflows/interfaces/utils.py @@ -50,7 +50,7 @@ class _FlattenInputSpec(BaseInterfaceInputSpec): desc="list of input data", ) in_meta = InputMultiObject( - traits.DictStrAny, + traits.Dict(traits.Str), mandatory=True, desc="list of metadata", ) @@ -61,12 +61,12 @@ class _FlattenOutputSpec(TraitedSpec): out_list = OutputMultiObject( traits.Tuple( File(exists=True), - traits.DictStrAny, + traits.Dict(traits.Str), ), desc="list of output files", ) out_data = OutputMultiObject(File(exists=True)) - out_meta = OutputMultiObject(traits.DictStrAny) + out_meta = OutputMultiObject(traits.Dict(traits.Str)) class Flatten(SimpleInterface): From 56758551cf81ce51173128fbd8c20e66f7baf5dd Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 17 Dec 2024 22:02:23 -0500 Subject: [PATCH 12/14] chore: Advertise Python 3.13 support --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d0d73f8712..c39f549eb0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] license = "Apache-2.0" requires-python = ">=3.9" From 5376caffd597a1d786099687753aaaba79ffa21a Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 18 Dec 2024 10:16:03 -0500 Subject: [PATCH 13/14] chore(ci): Remove unnecessary install step, move checkout to top --- .github/workflows/build-test-publish.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index f2b8826c26..8b410bbdad 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -74,6 +74,7 @@ jobs: dependencies: "pre" steps: + - uses: actions/checkout@v4 - uses: actions/cache@v4 with: path: /var/lib/apt @@ -127,8 +128,6 @@ jobs: ~/conda_pkgs_dir /home/runner/.cache/pip key: python-${{ matrix.python-version }}-${{ env.CACHE_NUM }} - restore-keys: | - python-${{ matrix.python-version }}-${{ env.CACHE_NUM }} - name: Install DataLad run: | conda install git-annex=*=alldep* @@ -137,13 +136,6 @@ jobs: - name: Install fsl and ANTs run: | conda install fsl-fugue fsl-topup ants - - uses: actions/checkout@v4 - - name: Install dependencies - timeout-minutes: 5 - run: | - pip install .[tests] - - - uses: actions/cache@v4 with: path: ~/.cache/templateflow From 9eb9cd6b216b63bd49797ed38c02059939242152 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 18 Dec 2024 10:26:54 -0500 Subject: [PATCH 14/14] chore(ci): Run cache_templateflow with a script runner --- .github/workflows/build-test-publish.yml | 2 +- tools/cache_templateflow.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 8b410bbdad..b77ac0196e 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -144,7 +144,7 @@ jobs: tf-cache- - name: Get TemplateFlow's required objects run: | - python tools/cache_templateflow.py + uv run tools/cache_templateflow.py - uses: actions/cache@v4 with: diff --git a/tools/cache_templateflow.py b/tools/cache_templateflow.py index 4397b2e3e9..814b56169d 100644 --- a/tools/cache_templateflow.py +++ b/tools/cache_templateflow.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +# /// script +# requires-python = ">=3.9" +# dependencies = [ +# "templateflow", +# ] +# /// from templateflow import api as tfapi tfapi.get("MNI152NLin2009cAsym", resolution=2, desc="brain", suffix="mask")