diff --git a/.circleci/config.yml b/.circleci/config.yml index a1effa019c..26369371b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -204,61 +204,6 @@ jobs: - /tmp/docker/cache/Dockerfile.base-pruned key: dockerfile-cache-v1-{{ .Branch }}-{{ checksum "/tmp/docker/cache/Dockerfile.base-pruned" }} - pypi_precheck: - machine: *machine_kwds - working_directory: /home/circleci/nipype - steps: - - checkout: - path: /home/circleci/nipype - - run: - name: Check pypi preconditions - command: | - pyenv local 3.6.5 - pip install --upgrade pip twine future wheel readme_renderer setuptools - python setup.py sdist bdist_wheel - twine check dist/* - - run: - name: Validate Python 3 installation - command: | - pyenv local 3.6.5 - pip install --upgrade pip - pip install dist/nipype-*-py3-none-any.whl - - run: - name: Validate Python 3.7 installation - command: | - pyenv local 3.7.0 - pip install --upgrade pip - # Pre-install a version of numpy that will not pass - pip install numpy==1.15.0 - pip install dist/nipype-*-py3-none-any.whl - # Numpy should be upgraded to >= 1.15.3 - test "$(pip show numpy | grep Version)" \> "Version: 1.15.2" - - run: - name: Check python_requires prevents installation on Python 3.3 - command: | - pyenv install 3.3.7 - pyenv local 3.3.7 - FAIL=false - pip install dist/nipype-*-py2.py3-none-any.whl || FAIL=true - $FAIL - - store_artifacts: - path: /home/circleci/nipype/dist - - deploy_pypi: - machine: *machine_kwds - working_directory: /home/circleci/nipype - steps: - - checkout: - path: /home/circleci/nipype - - run: - name: Deploy to PyPI - command: | - pyenv local 3.6.5 - pip install --upgrade twine wheel readme_renderer setuptools - python setup.py check -r -s - python setup.py sdist bdist_wheel - twine upload dist/* - update_feedstock: machine: *machine_kwds working_directory: /home/circleci/nipype @@ -295,12 +240,6 @@ workflows: version: 2 build_test_deploy: jobs: - - pypi_precheck: - filters: - branches: - only: /(rel|dev)\/.*/ - tags: - only: /.*/ - compare_base_dockerfiles: filters: branches: @@ -325,19 +264,10 @@ workflows: only: /.*/ requires: - test_pytest - - deploy_pypi: - filters: - branches: - ignore: /.*/ - tags: - only: /.*/ - requires: - - pypi_precheck - - test_pytest - update_feedstock: context: nipybot filters: branches: - only: /rel\/.*/ + only: /rel\/\d.*/ tags: only: /.*/ diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000000..fe1fbe50d2 --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,61 @@ +name: Packaging + +on: + push: + branches: + - master + - maint/* + - rel/* + tags: + - '*' + +defaults: + run: + shell: bash + +jobs: + package: + # Build packages and upload + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + python-version: 3.8 + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Display Python version + run: python -c "import sys; print(sys.version)" + - name: Create virtual environment + run: tools/ci/create_venv.sh + - name: Build sdist + run: tools/ci/build_archive.sh + env: + INSTALL_TYPE: sdist + - name: Build wheel + run: tools/ci/build_archive.sh + env: + INSTALL_TYPE: wheel + ### Temporary + - name: Check packages with twine + run: | + pip install twine + twine check dist/* + ### Switch back to this if we figure out who has permissions on test.pypi.org + # - name: Test PyPI upload + # uses: pypa/gh-action-pypi-publish@master + # with: + # user: __token__ + # password: ${{ secrets.TEST_PYPI_API_TOKEN }} + # repository_url: https://test.pypi.org/legacy/ + # skip_existing: true + - name: Upload to PyPI (on tags) + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.mailmap b/.mailmap index f603849d24..a233bff1e0 100644 --- a/.mailmap +++ b/.mailmap @@ -55,6 +55,7 @@ David Mordom David Welch Dimitri Papadopoulos Orfanos Dmytro Belevtsoff +Dorian Vogel Dylan M. Nielson Dylan M. Nielson Eduard Ort @@ -73,6 +74,7 @@ Gilles de Hollander Gio Piantoni Guillaume Flandin Hans Johnson +Henry Jones Horea Christian Hrvoje Stojic Isaac Schwabacher @@ -153,6 +155,8 @@ Ranjit Khanuja Rastko Ćirić Rastko Ćirić Rastko Ćirić +Raunak Jalan +Raunak Jalan <41023976+RaunakJalan@users.noreply.github.com> Ross Markello Russell Poldrack Russell Poldrack @@ -175,6 +179,9 @@ Steven Giavasis Steven Tilley Sulantha Mathotaarachchi +Tim Robert-Fitzgerald +Tom Close +Tom Close Tristan Glatard Victor Férat Victor Férat diff --git a/.zenodo.json b/.zenodo.json index 6c8db536d2..83764c5417 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -230,6 +230,11 @@ "name": "Mancini, Matteo", "orcid": "0000-0001-7194-4568" }, + { + "affiliation": "University of Sydney", + "name": "Close, Thomas", + "orcid": "0000-0002-4160-2134" + }, { "affiliation": "National Institute of Mental Health", "name": "Nielson, Dylan M.", @@ -246,15 +251,30 @@ { "name": "Mordom, David" }, + { + "affiliation": "CIBIT, UC", + "name": "Machado, F\u00e1tima", + "orcid": "0000-0001-8878-1750" + }, { "affiliation": "ARAMIS LAB, Brain and Spine Institute (ICM), Paris, France.", "name": "Guillon, Je\u0301re\u0301my", "orcid": "0000-0002-2672-7510" }, + { + "affiliation": "Charite Universitatsmedizin Berlin, Germany", + "name": "Waller, Lea", + "orcid": "0000-0002-3239-6957" + }, { "affiliation": "Indiana University, IN, USA", "name": "Koudoro, Serge" }, + { + "affiliation": "Penn Statistics in Imaging and Visualization Endeavor, University of Pennsylvania", + "name": "Robert-Fitzgerald, Timothy", + "orcid": "0000-0001-8303-8001" + }, { "affiliation": "Donders Institute for Brain, Cognition and Behavior, Center for Cognitive Neuroimaging", "name": "Chetverikov, Andrey", @@ -334,6 +354,11 @@ { "name": "Schwartz, Yannick" }, + { + "affiliation": "The University of Iowa", + "name": "Ghayoor, Ali", + "orcid": "0000-0002-8858-1254" + }, { "affiliation": "NIMH IRP", "name": "Lee, John A.", @@ -403,13 +428,12 @@ "orcid": "0000-0003-2766-8425" }, { - "affiliation": "University of Iowa", - "name": "Welch, David" + "affiliation": "Sagol School of Neuroscience, Tel Aviv University", + "name": "Baratz, Zvi" }, { - "affiliation": "Charite Universitatsmedizin Berlin, Germany", - "name": "Waller, Lea", - "orcid": "0000-0002-3239-6957" + "affiliation": "University of Iowa", + "name": "Welch, David" }, { "affiliation": "Max Planck Institute for Human Cognitive and Brain Sciences", @@ -421,11 +445,6 @@ "name": "Triplett, William", "orcid": "0000-0002-9546-1306" }, - { - "affiliation": "The University of Iowa", - "name": "Ghayoor, Ali", - "orcid": "0000-0002-8858-1254" - }, { "affiliation": "Child Mind Institute", "name": "Craddock, R. Cameron", @@ -614,6 +633,9 @@ "name": "Lee, Nat", "orcid": "0000-0001-9308-9988" }, + { + "name": "Jalan, Raunak" + }, { "name": "Inati, Souheil" }, @@ -697,10 +719,6 @@ "name": "Andberg, Sami Kristian", "orcid": "0000-0002-5650-3964" }, - { - "affiliation": "Sagol School of Neuroscience, Tel Aviv University", - "name": "Baratz, Zvi" - }, { "name": "Matsubara, K" }, @@ -711,11 +729,6 @@ { "name": "Marina, Ana" }, - { - "affiliation": "University of Sydney", - "name": "Close, Thomas", - "orcid": "0000-0002-4160-2134" - }, { "name": "Davison, Andrew" }, @@ -741,9 +754,19 @@ { "name": "Shachnev, Dmitry" }, + { + "affiliation": "University of Applied Sciences and Arts Northwestern Switzerland", + "name": "Vogel, Dorian", + "orcid": "0000-0003-3445-576X" + }, { "name": "Flandin, Guillaume" }, + { + "affiliation": "Stanford University and the University of Chicago", + "name": "Jones, Henry", + "orcid": "0000-0001-7719-3646" + }, { "affiliation": "Athinoula A. Martinos Center for Biomedical Imaging, Department of Radiology, Massachusetts General Hospital, Charlestown, MA, USA", "name": "Gonzalez, Ivan", @@ -790,22 +813,19 @@ "name": "Broderick, William", "orcid": "0000-0002-8999-9003" }, - { - "name": "Tambini, Arielle" - }, { "affiliation": "Weill Cornell Medicine", "name": "Xie, Xihe", "orcid": "0000-0001-6595-2473" }, + { + "name": "Tambini, Arielle" + }, { "affiliation": "Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig, Germany.", "name": "Mihai, Paul Glad", "orcid": "0000-0001-5715-6442" }, - { - "name": "Jalan, Raunak", - }, { "affiliation": "Department of Psychology, Stanford University", "name": "Gorgolewski, Krzysztof J.", @@ -815,11 +835,6 @@ "affiliation": "MIT, HMS", "name": "Ghosh, Satrajit", "orcid": "0000-0002-5312-6729" - }, - { - "affiliation": "CIBIT, UC", - "name": "Machado, Fátima", - "orcid": "0000-0001-8878-1750" } ], "keywords": [ diff --git a/doc/changelog/1.X.X-changelog.rst b/doc/changelog/1.X.X-changelog.rst index 822e22547f..6d8cd64652 100644 --- a/doc/changelog/1.X.X-changelog.rst +++ b/doc/changelog/1.X.X-changelog.rst @@ -1,3 +1,31 @@ +1.6.1 (June 16, 2021) +===================== + +Bug-fix release in the 1.6.x series. + +(`Full changelog `__) + + * FIX: Set DistributedPluginBase.refidx type correctly (https://github.com/nipy/nipype/pull/3340) + * FIX: change fsl interface randomise --f_only to --fonly for #3322 (https://github.com/nipy/nipype/pull/3325) + * FIX: BET raising "No image files match: ..." with very long file names (https://github.com/nipy/nipype/pull/3309) + * FIX: Update SmoothEstimateOutputSpec resels description (https://github.com/nipy/nipype/pull/3316) + * ENH: Adds interfaces for MRtrix utils shconv and sh2amp (https://github.com/nipy/nipype/pull/3280) + * ENH: Interface for R (https://github.com/nipy/nipype/pull/3291) + * ENH: Add CAT12 interfaces (https://github.com/nipy/nipype/pull/3310) + * ENH: AFNI 3dNetCorr as afni.NetCorr (https://github.com/nipy/nipype/pull/3263) + * ENH: Skip newline before Python call in batch submission to facilitate containerized runs (https://github.com/nipy/nipype/pull/3297) + * ENH: Add new dwifslpreproc interface for MRtrix3 (https://github.com/nipy/nipype/pull/3278) + * REF: Cache nodes in workflow to speed up construction, other optimizations (https://github.com/nipy/nipype/pull/3331) + * DOC: Fixed Developer Setup Link in install.rst (https://github.com/nipy/nipype/pull/3330) + * MNT: Blacklist Dipy 1.4.1 (https://github.com/nipy/nipype/pull/3335) + * MNT: Drop support for numpy < 1.15.3 (https://github.com/nipy/nipype/pull/3284) + * CI: Build docker images with Python 3.8 (https://github.com/nipy/nipype/pull/3287) + * CI: Drop Circle doc builds (https://github.com/nipy/nipype/pull/3338) + * CI: Drop Travis (https://github.com/nipy/nipype/pull/3332) + * CI: Build docker images with Python 3.8 (https://github.com/nipy/nipype/pull/3287) + * CI: Add specs and style checks (https://github.com/nipy/nipype/pull/3321) + * CI: Move from Travis to GitHub actions (https://github.com/nipy/nipype/pull/3318) + 1.6.0 (November 28, 2020) ========================= diff --git a/doc/interfaces.rst b/doc/interfaces.rst index dc83450b5a..107eb6519b 100644 --- a/doc/interfaces.rst +++ b/doc/interfaces.rst @@ -8,7 +8,7 @@ Interfaces and Workflows :Release: |version| :Date: |today| -Previous versions: `1.5.1 `_ `1.5.0 `_ +Previous versions: `1.6.0 `_ `1.5.1 `_ Workflows --------- diff --git a/nipype/algorithms/confounds.py b/nipype/algorithms/confounds.py index 1aa88d6e62..18c268b461 100644 --- a/nipype/algorithms/confounds.py +++ b/nipype/algorithms/confounds.py @@ -613,7 +613,7 @@ def _run_interface(self, runtime): if len(mask_images) == 0: img = nb.Nifti1Image( - np.ones(imgseries.shape[:3], dtype=np.bool), + np.ones(imgseries.shape[:3], dtype=bool), affine=imgseries.affine, header=imgseries.header, ) @@ -835,7 +835,7 @@ def _process_masks(self, mask_images, timeseries=None): self._mask_files = [] timeseries = np.asanyarray(timeseries) for i, img in enumerate(mask_images): - mask = np.asanyarray(img.dataobj).astype(np.bool) + mask = np.asanyarray(img.dataobj).astype(bool) imgseries = timeseries[mask, :] imgseries = regress_poly(2, imgseries)[0] tSTD = _compute_tSTD(imgseries, 0, axis=-1) @@ -1379,7 +1379,7 @@ def compute_noise_components( md_retained = [] for name, img in zip(mask_names, mask_images): - mask = np.asanyarray(nb.squeeze_image(img).dataobj).astype(np.bool) + mask = np.asanyarray(nb.squeeze_image(img).dataobj).astype(bool) if imgseries.shape[:3] != mask.shape: raise ValueError( "Inputs for CompCor, timeseries and mask, do not have " diff --git a/nipype/algorithms/metrics.py b/nipype/algorithms/metrics.py index e399becb65..b314197f77 100644 --- a/nipype/algorithms/metrics.py +++ b/nipype/algorithms/metrics.py @@ -88,10 +88,10 @@ def _get_coordinates(self, data, affine): def _eucl_min(self, nii1, nii2): from scipy.spatial.distance import cdist, euclidean - origdata1 = np.asanyarray(nii1.dataobj).astype(np.bool) + origdata1 = np.asanyarray(nii1.dataobj).astype(bool) border1 = self._find_border(origdata1) - origdata2 = np.asanyarray(nii2.dataobj).astype(np.bool) + origdata2 = np.asanyarray(nii2.dataobj).astype(bool) border2 = self._find_border(origdata2) set1_coordinates = self._get_coordinates(border1, nii1.affine) @@ -134,10 +134,10 @@ def _eucl_cog(self, nii1, nii2): def _eucl_mean(self, nii1, nii2, weighted=False): from scipy.spatial.distance import cdist - origdata1 = np.asanyarray(nii1.dataobj).astype(np.bool) + origdata1 = np.asanyarray(nii1.dataobj).astype(bool) border1 = self._find_border(origdata1) - origdata2 = np.asanyarray(nii2.dataobj).astype(np.bool) + origdata2 = np.asanyarray(nii2.dataobj).astype(bool) set1_coordinates = self._get_coordinates(border1, nii1.affine) set2_coordinates = self._get_coordinates(origdata2, nii2.affine) diff --git a/nipype/info.py b/nipype/info.py index 7f6899cdd0..4f065939ed 100644 --- a/nipype/info.py +++ b/nipype/info.py @@ -5,7 +5,7 @@ # nipype version information # Remove -dev for release -__version__ = "1.6.0" +__version__ = "1.6.1" def get_nipype_gitversion(): diff --git a/nipype/interfaces/afni/base.py b/nipype/interfaces/afni/base.py index 20a4a9b4d6..31a9f7585d 100644 --- a/nipype/interfaces/afni/base.py +++ b/nipype/interfaces/afni/base.py @@ -98,7 +98,7 @@ def standard_image(img_name): resource_monitor=False, terminal_output="allatonce", ).run() - if clout.runtime.returncode is not 0: + if clout.runtime.returncode != 0: return None out = clout.runtime.stdout diff --git a/nipype/interfaces/base/traits_extension.py b/nipype/interfaces/base/traits_extension.py index b513a17eee..9ac4aa1839 100644 --- a/nipype/interfaces/base/traits_extension.py +++ b/nipype/interfaces/base/traits_extension.py @@ -19,7 +19,7 @@ (usually by Robert Kern). """ -from collections import Sequence +from collections.abc import Sequence # perform all external trait imports here from traits import __version__ as traits_version diff --git a/nipype/interfaces/diffusion_toolkit/base.py b/nipype/interfaces/diffusion_toolkit/base.py index b4b5ba1893..2068f18988 100644 --- a/nipype/interfaces/diffusion_toolkit/base.py +++ b/nipype/interfaces/diffusion_toolkit/base.py @@ -47,7 +47,7 @@ def version(): """ clout = CommandLine(command="dti_recon", terminal_output="allatonce").run() - if clout.runtime.returncode is not 0: + if clout.runtime.returncode != 0: return None dtirecon = clout.runtime.stdout diff --git a/nipype/utils/misc.py b/nipype/utils/misc.py index 3531610800..8ec6ee5342 100644 --- a/nipype/utils/misc.py +++ b/nipype/utils/misc.py @@ -6,7 +6,7 @@ import os import sys import re -from collections import Iterator +from collections.abc import Iterator from warnings import warn from distutils.version import LooseVersion @@ -34,7 +34,7 @@ def atoi(text): def natural_keys(text): if isinstance(text, tuple): text = text[0] - return [atoi(c) for c in re.split("(\d+)", text)] + return [atoi(c) for c in re.split(r"(\d+)", text)] return sorted(l, key=natural_keys) diff --git a/nipype/utils/tests/test_filemanip.py b/nipype/utils/tests/test_filemanip.py index e8da256261..299029a8d2 100644 --- a/nipype/utils/tests/test_filemanip.py +++ b/nipype/utils/tests/test_filemanip.py @@ -154,7 +154,7 @@ def test_copyfiles(_temp_analyze_files, _temp_analyze_files_prime): def test_linkchain(_temp_analyze_files): - if os.name is not "posix": + if os.name != "posix": return orig_img, orig_hdr = _temp_analyze_files pth, fname = os.path.split(orig_img) @@ -230,7 +230,7 @@ def test_recopy(_temp_analyze_files): def test_copyfallback(_temp_analyze_files): - if os.name is not "posix": + if os.name != "posix": return orig_img, orig_hdr = _temp_analyze_files pth, imgname = os.path.split(orig_img) diff --git a/setup.py b/setup.py index 1a666c6115..046124fde8 100755 --- a/setup.py +++ b/setup.py @@ -119,6 +119,7 @@ def main(): maintainer_email=ldict["MAINTAINER_EMAIL"], description=ldict["DESCRIPTION"], long_description=ldict["LONG_DESCRIPTION"], + long_description_content_type="text/x-rst", url=ldict["URL"], download_url=ldict["DOWNLOAD_URL"], license=ldict["LICENSE"],