diff --git a/.coveragerc b/.coveragerc index ea62a2eb46..c69c0eef3c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -4,6 +4,5 @@ source = nipype include = */nipype/* omit = */nipype/external/* - */nipype/workflows/* */nipype/fixes/* */setup.py diff --git a/.travis.yml b/.travis.yml index 6dbefbd97c..ca29323e5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,15 +36,10 @@ install: conda install -y nipype && rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype* && pip install -r requirements.txt && - pip install -e .[$NIPYPE_EXTRAS] && - export COVERAGE_PROCESS_START=$(pwd)/.coveragerc && - export COVERAGE_DATA_FILE=$(pwd)/.coverage && - echo "data_file = ${COVERAGE_DATA_FILE}" >> ${COVERAGE_PROCESS_START}; } + pip install -e .[$NIPYPE_EXTRAS]; } - travis_retry inst script: -- py.test --doctest-modules --cov=nipype nipype -after_success: -- bash <(curl -s https://codecov.io/bash) -t ac172a50-8e66-42e5-8822-5373fcf54686 -cF unittests +- py.test --doctest-modules nipype deploy: provider: pypi user: satra diff --git a/nipype/__init__.py b/nipype/__init__.py index b633736023..c7ce79c99e 100644 --- a/nipype/__init__.py +++ b/nipype/__init__.py @@ -11,7 +11,6 @@ STATUS as __status__, __version__) from .utils.config import NipypeConfig -from .fixes.numpy.testing import nosetester from .utils.logger import Logging from .refs import due @@ -24,37 +23,37 @@ config = NipypeConfig() logging = Logging(config) +#NOTE_dj: it has to be changed to python +#class _NoseTester(nosetester.NoseTester): +# """ Subclass numpy's NoseTester to add doctests by default +# """ -class _NoseTester(nosetester.NoseTester): - """ Subclass numpy's NoseTester to add doctests by default - """ +# def _get_custom_doctester(self): +# return None - def _get_custom_doctester(self): - return None +# def test(self, label='fast', verbose=1, extra_argv=['--exe'], +# doctests=True, coverage=False): +# """Run the full test suite +# +# Examples +# -------- +# This will run the test suite and stop at the first failing +# example +# >>> from nipype import test +# >>> test(extra_argv=['--exe', '-sx']) # doctest: +SKIP +# """ +# return super(_NoseTester, self).test(label=label, +# verbose=verbose, +# extra_argv=extra_argv, +# doctests=doctests, +# coverage=coverage) - def test(self, label='fast', verbose=1, extra_argv=['--exe'], - doctests=True, coverage=False): - """Run the full test suite - - Examples - -------- - This will run the test suite and stop at the first failing - example - >>> from nipype import test - >>> test(extra_argv=['--exe', '-sx']) # doctest: +SKIP - """ - return super(_NoseTester, self).test(label=label, - verbose=verbose, - extra_argv=extra_argv, - doctests=doctests, - coverage=coverage) - -try: - test = _NoseTester(raise_warnings="release").test -except TypeError: +#try: +# test = _NoseTester(raise_warnings="release").test +#except TypeError: # Older versions of numpy do not have a raise_warnings argument - test = _NoseTester().test -del nosetester +# test = _NoseTester().test +#del nosetester # Set up package information function from .pkg_info import get_pkg_info as _get_pkg_info @@ -62,10 +61,10 @@ def test(self, label='fast', verbose=1, extra_argv=['--exe'], # If this file is exec after being imported, the following lines will # fail -try: - del Tester -except: - pass +#try: +# del Tester +#except: +# pass from .pipeline import Node, MapNode, JoinNode, Workflow diff --git a/nipype/algorithms/tests/test_auto_ACompCor.py b/nipype/algorithms/tests/test_auto_ACompCor.py new file mode 100644 index 0000000000..b28b6086da --- /dev/null +++ b/nipype/algorithms/tests/test_auto_ACompCor.py @@ -0,0 +1,36 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..confounds import ACompCor + + +def test_ACompCor_inputs(): + input_map = dict(components_file=dict(usedefault=True, + ), + header=dict(), + ignore_exception=dict(nohash=True, + usedefault=True, + ), + mask_file=dict(), + num_components=dict(usedefault=True, + ), + realigned_file=dict(mandatory=True, + ), + regress_poly_degree=dict(usedefault=True, + ), + use_regress_poly=dict(usedefault=True, + ), + ) + inputs = ACompCor.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_ACompCor_outputs(): + output_map = dict(components_file=dict(), + ) + outputs = ACompCor.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/algorithms/tests/test_auto_TCompCor.py b/nipype/algorithms/tests/test_auto_TCompCor.py index 8b5984527e..e1da90befb 100644 --- a/nipype/algorithms/tests/test_auto_TCompCor.py +++ b/nipype/algorithms/tests/test_auto_TCompCor.py @@ -29,8 +29,22 @@ def test_TCompCor_inputs(): def test_TCompCor_outputs(): - output_map = dict(components_file=dict(), - high_variance_mask=dict() + output_map = dict(components_file=dict(usedefault=True, + ), + header=dict(), + high_variance_mask=dict(), + ignore_exception=dict(nohash=True, + usedefault=True, + ), + mask_file=dict(), + num_components=dict(usedefault=True, + ), + realigned_file=dict(mandatory=True, + ), + regress_poly_degree=dict(usedefault=True, + ), + use_regress_poly=dict(usedefault=True, + ), ) outputs = TCompCor.output_spec() diff --git a/nipype/algorithms/tests/test_icc_anova.py b/nipype/algorithms/tests/test_icc_anova.py index 8177c89940..65b1e9c6ed 100644 --- a/nipype/algorithms/tests/test_icc_anova.py +++ b/nipype/algorithms/tests/test_icc_anova.py @@ -19,4 +19,4 @@ def test_ICC_rep_anova(): assert round(icc, 2) == 0.71 assert dfc == 3 assert dfe == 15 - assert r_var / (r_var + e_var) == icc + assert np.isclose(r_var / (r_var + e_var), icc) diff --git a/nipype/fixes/README.txt b/nipype/fixes/README.txt deleted file mode 100644 index dd183c1739..0000000000 --- a/nipype/fixes/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -This directory is meant to contain fixes to external packages, such as scipy, numpy -that are meant to eventually be moved upstream to these packages. - -When these changes find their way upstream and are released, -they can be deleted from the "fixes" directory when new versions of -NIPY are released. - -PACKAGES/MODULES: ---------- -scipy/stats_models: corresponds to module "scipy.stats.models" \ No newline at end of file diff --git a/nipype/fixes/__init__.py b/nipype/fixes/__init__.py deleted file mode 100644 index a04158a3ae..0000000000 --- a/nipype/fixes/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# We import numpy fixes during init of the testing package. We need to delay -# import of the testing package until after it has initialized - -from os.path import dirname - -# Cache for the actual testing functin -_tester = None - - -def test(*args, **kwargs): - """ test function for fixes subpackage - - This function defers import of the testing machinery so it can import from - us first. - - See nipy.test docstring for parameters and return values - """ - global _tester - if _tester is None: - from nipy.testing import Tester - _tester = Tester(dirname(__file__)).test - return _tester(*args, **kwargs) - -# Remind nose not to test the test function -test.__test__ = False diff --git a/nipype/fixes/numpy/__init__.py b/nipype/fixes/numpy/__init__.py deleted file mode 100644 index 7850043b8f..0000000000 --- a/nipype/fixes/numpy/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -# numpy fixes package diff --git a/nipype/fixes/numpy/testing/__init__.py b/nipype/fixes/numpy/testing/__init__.py deleted file mode 100644 index 87ed9ba529..0000000000 --- a/nipype/fixes/numpy/testing/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -# Package init for fixes.numpy.testing diff --git a/nipype/fixes/numpy/testing/noseclasses.py b/nipype/fixes/numpy/testing/noseclasses.py deleted file mode 100644 index db7ae585e1..0000000000 --- a/nipype/fixes/numpy/testing/noseclasses.py +++ /dev/null @@ -1,359 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import -from builtins import object -# These classes implement a doctest runner plugin for nose, a "known failure" -# error class, and a customized TestProgram for NumPy. - -# Because this module imports nose directly, it should not -# be used except by nosetester.py to avoid a general NumPy -# dependency on nose. - -import os -import doctest - -import nose -from nose.plugins import doctests as npd -from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin -from nose.plugins.base import Plugin -from nose.util import src -import numpy -from .nosetester import get_package_name -import inspect - -# Some of the classes in this module begin with 'Numpy' to clearly distinguish -# them from the plethora of very similar names from nose/unittest/doctest - -# ----------------------------------------------------------------------------- -# Modified version of the one in the stdlib, that fixes a python bug (doctests -# not found in extension modules, http://bugs.python.org/issue3158) - - -class NumpyDocTestFinder(doctest.DocTestFinder): - - def _from_module(self, module, object): - """ - Return true if the given object is defined in the given - module. - """ - if module is None: - # print '_fm C1' # dbg - return True - elif inspect.isfunction(object): - # print '_fm C2' # dbg - return module.__dict__ is object.__globals__ - elif inspect.isbuiltin(object): - # print '_fm C2-1' # dbg - return module.__name__ == object.__module__ - elif inspect.isclass(object): - # print '_fm C3' # dbg - return module.__name__ == object.__module__ - elif inspect.ismethod(object): - # This one may be a bug in cython that fails to correctly set the - # __module__ attribute of methods, but since the same error is easy - # to make by extension code writers, having this safety in place - # isn't such a bad idea - # print '_fm C3-1' # dbg - return module.__name__ == object.__self__.__class__.__module__ - elif inspect.getmodule(object) is not None: - # print '_fm C4' # dbg - # print 'C4 mod',module,'obj',object # dbg - return module is inspect.getmodule(object) - elif hasattr(object, '__module__'): - # print '_fm C5' # dbg - return module.__name__ == object.__module__ - elif isinstance(object, property): - # print '_fm C6' # dbg - return True # [XX] no way not be sure. - else: - raise ValueError("object must be a class or function") - - def _find(self, tests, obj, name, module, source_lines, globs, seen): - """ - Find tests for the given object and any contained objects, and - add them to `tests`. - """ - - doctest.DocTestFinder._find(self, tests, obj, name, module, - source_lines, globs, seen) - - # Below we re-run pieces of the above method with manual modifications, - # because the original code is buggy and fails to correctly identify - # doctests in extension modules. - - # Local shorthands - from inspect import isroutine, isclass, ismodule, isfunction, \ - ismethod - - # Look for tests in a module's contained objects. - if ismodule(obj) and self._recurse: - for valname, val in list(obj.__dict__.items()): - valname1 = '%s.%s' % (name, valname) - if ((isroutine(val) or isclass(val)) and - self._from_module(module, val)): - - self._find(tests, val, valname1, module, source_lines, - globs, seen) - - # Look for tests in a class's contained objects. - if isclass(obj) and self._recurse: - # print 'RECURSE into class:',obj # dbg - for valname, val in list(obj.__dict__.items()): - # valname1 = '%s.%s' % (name, valname) # dbg - # print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg - # Special handling for staticmethod/classmethod. - if isinstance(val, staticmethod): - val = getattr(obj, valname) - if isinstance(val, classmethod): - val = getattr(obj, valname).__func__ - - # Recurse to methods, properties, and nested classes. - if ((isfunction(val) or isclass(val) or - ismethod(val) or isinstance(val, property)) and - self._from_module(module, val)): - valname = '%s.%s' % (name, valname) - self._find(tests, val, valname, module, source_lines, - globs, seen) - - -# second-chance checker; if the default comparison doesn't -# pass, then see if the expected output string contains flags that -# tell us to ignore the output -class NumpyOutputChecker(doctest.OutputChecker): - def check_output(self, want, got, optionflags): - ret = doctest.OutputChecker.check_output(self, want, got, - optionflags) - if not ret: - if "#random" in want: - return True - - # it would be useful to normalize endianness so that - # bigendian machines don't fail all the tests (and there are - # actually some bigendian examples in the doctests). Let's try - # making them all little endian - got = got.replace("'>", "'<") - want = want.replace("'>", "'<") - - # try to normalize out 32 and 64 bit default int sizes - for sz in [4, 8]: - got = got.replace("'>> import numpy as np - >>> np.testing.nosetester.get_package_name('nonsense') # doctest: +ALLOW_UNICODE - 'numpy' - - """ - - fullpath = filepath[:] - pkg_name = [] - while 'site-packages' in filepath or 'dist-packages' in filepath: - filepath, p2 = os.path.split(filepath) - if p2 in ('site-packages', 'dist-packages'): - break - pkg_name.append(p2) - - # if package name determination failed, just default to numpy/scipy - if not pkg_name: - if 'scipy' in fullpath: - return 'scipy' - else: - return 'numpy' - - # otherwise, reverse to get correct order and return - pkg_name.reverse() - - # don't include the outer egg directory - if pkg_name[0].endswith('.egg'): - pkg_name.pop(0) - - return '.'.join(pkg_name) - - -def import_nose(): - """ Import nose only when needed. - """ - fine_nose = True - minimum_nose_version = (0, 10, 0) - try: - import nose - from nose.tools import raises - except ImportError: - fine_nose = False - else: - if nose.__versioninfo__ < minimum_nose_version: - fine_nose = False - - if not fine_nose: - msg = 'Need nose >= %d.%d.%d for tests - see ' \ - 'http://somethingaboutorange.com/mrl/projects/nose' % \ - minimum_nose_version - - raise ImportError(msg) - - return nose - - -def run_module_suite(file_to_run=None): - if file_to_run is None: - f = sys._getframe(1) - file_to_run = f.f_locals.get('__file__', None) - if file_to_run is None: - raise AssertionError - - import_nose().run(argv=['', file_to_run]) - - -class NoseTester(object): - """ - Nose test runner. - - This class is made available as numpy.testing.Tester, and a test function - is typically added to a package's __init__.py like so:: - - from numpy.testing import Tester - test = Tester().test - - Calling this test function finds and runs all tests associated with the - package and all its sub-packages. - - Attributes - ---------- - package_path : str - Full path to the package to test. - package_name : str - Name of the package to test. - - Parameters - ---------- - package : module, str or None - The package to test. If a string, this should be the full path to - the package. If None (default), `package` is set to the module from - which `NoseTester` is initialized. - - """ - # Stuff to exclude from tests. These are from numpy.distutils - excludes = ['f2py_ext', - 'f2py_f90_ext', - 'gen_ext', - 'pyrex_ext', - 'swig_ext'] - - def __init__(self, package=None): - ''' Test class init - - Parameters - ---------- - package : string or module - If string, gives full path to package - If None, extract calling module path - Default is None - ''' - package_name = None - if package is None: - f = sys._getframe(1) - package_path = f.f_locals.get('__file__', None) - if package_path is None: - raise AssertionError - package_path = os.path.dirname(package_path) - package_name = f.f_locals.get('__name__', None) - elif isinstance(package, type(os)): - package_path = os.path.dirname(package.__file__) - package_name = getattr(package, '__name__', None) - else: - package_path = str(package) - - self.package_path = package_path - - # find the package name under test; this name is used to limit coverage - # reporting (if enabled) - if package_name is None: - package_name = get_package_name(package_path) - self.package_name = package_name - - def _test_argv(self, label, verbose, extra_argv): - ''' Generate argv for nosetest command - - Parameters - ---------- - label : {'fast', 'full', '', attribute identifier}, optional - see ``test`` docstring - verbose : int, optional - Verbosity value for test outputs, in the range 1-10. Default is 1. - extra_argv : list, optional - List with any extra arguments to pass to nosetests. - - Returns - ------- - argv : list - command line arguments that will be passed to nose - ''' - argv = [__file__, self.package_path, '-s'] - if label and label != 'full': - if not isinstance(label, (str, bytes)): - raise TypeError('Selection label should be a string') - if label == 'fast': - label = 'not slow' - argv += ['-A', label] - argv += ['--verbosity', str(verbose)] - if extra_argv: - argv += extra_argv - return argv - - def _show_system_info(self): - nose = import_nose() - - import numpy - print("NumPy version %s" % numpy.__version__) - npdir = os.path.dirname(numpy.__file__) - print("NumPy is installed in %s" % npdir) - - if 'scipy' in self.package_name: - import scipy - print("SciPy version %s" % scipy.__version__) - spdir = os.path.dirname(scipy.__file__) - print("SciPy is installed in %s" % spdir) - - pyversion = sys.version.replace('\n', '') - print("Python version %s" % pyversion) - print("nose version %d.%d.%d" % nose.__versioninfo__) - - def _get_custom_doctester(self): - """ Return instantiated plugin for doctests - - Allows subclassing of this class to override doctester - - A return value of None means use the nose builtin doctest plugin - """ - from .noseclasses import NumpyDoctest - return NumpyDoctest() - - def prepare_test_args(self, label='fast', verbose=1, extra_argv=None, - doctests=False, coverage=False): - """ - Run tests for module using nose. - - This method does the heavy lifting for the `test` method. It takes all - the same arguments, for details see `test`. - - See Also - -------- - test - - """ - # fail with nice error message if nose is not present - import_nose() - # compile argv - argv = self._test_argv(label, verbose, extra_argv) - # bypass tests noted for exclude - for ename in self.excludes: - argv += ['--exclude', ename] - # our way of doing coverage - if coverage: - argv += ['--cover-package=%s' % self.package_name, '--with-coverage', - '--cover-tests', '--cover-inclusive', '--cover-erase'] - # construct list of plugins - import nose.plugins.builtin - from .noseclasses import KnownFailure, Unplugger - plugins = [KnownFailure()] - plugins += [p() for p in nose.plugins.builtin.plugins] - # add doctesting if required - doctest_argv = '--with-doctest' in argv - if doctests is False and doctest_argv: - doctests = True - plug = self._get_custom_doctester() - if plug is None: - # use standard doctesting - if doctests and not doctest_argv: - argv += ['--with-doctest'] - else: # custom doctesting - if doctest_argv: # in fact the unplugger would take care of this - argv.remove('--with-doctest') - plugins += [Unplugger('doctest'), plug] - if doctests: - argv += ['--with-' + plug.name] - return argv, plugins - - def test(self, label='fast', verbose=1, extra_argv=None, doctests=False, - coverage=False): - """ - Run tests for module using nose. - - Parameters - ---------- - label : {'fast', 'full', '', attribute identifier}, optional - Identifies the tests to run. This can be a string to pass to - the nosetests executable with the '-A' option, or one of several - special values. Special values are: - * 'fast' - the default - which corresponds to the ``nosetests -A`` - option of 'not slow'. - * 'full' - fast (as above) and slow tests as in the - 'no -A' option to nosetests - this is the same as ''. - * None or '' - run all tests. - attribute_identifier - string passed directly to nosetests as '-A'. - verbose : int, optional - Verbosity value for test outputs, in the range 1-10. Default is 1. - extra_argv : list, optional - List with any extra arguments to pass to nosetests. - doctests : bool, optional - If True, run doctests in module. Default is False. - coverage : bool, optional - If True, report coverage of NumPy code. Default is False. - (This requires the `coverage module: - `_). - - Returns - ------- - result : object - Returns the result of running the tests as a - ``nose.result.TextTestResult`` object. - - Notes - ----- - Each NumPy module exposes `test` in its namespace to run all tests for it. - For example, to run all tests for numpy.lib: - - >>> np.lib.test() #doctest: +SKIP - - Examples - -------- - >>> result = np.lib.test() #doctest: +SKIP - Running unit tests for numpy.lib - ... - Ran 976 tests in 3.933s - - OK - - >>> result.errors #doctest: +SKIP - [] - >>> result.knownfail #doctest: +SKIP - [] - """ - - # cap verbosity at 3 because nose becomes *very* verbose beyond that - verbose = min(verbose, 3) - - from . import utils - utils.verbose = verbose - - if doctests: - print("Running unit tests and doctests for %s" % self.package_name) - else: - print("Running unit tests for %s" % self.package_name) - - self._show_system_info() - - # reset doctest state on every run - import doctest - doctest.master = None - - argv, plugins = self.prepare_test_args(label, verbose, extra_argv, - doctests, coverage) - from .noseclasses import NumpyTestProgram - t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins) - return t.result - - def bench(self, label='fast', verbose=1, extra_argv=None): - """ - Run benchmarks for module using nose. - - Parameters - ---------- - label : {'fast', 'full', '', attribute identifier}, optional - Identifies the benchmarks to run. This can be a string to pass to - the nosetests executable with the '-A' option, or one of several - special values. Special values are: - * 'fast' - the default - which corresponds to the ``nosetests -A`` - option of 'not slow'. - * 'full' - fast (as above) and slow benchmarks as in the - 'no -A' option to nosetests - this is the same as ''. - * None or '' - run all tests. - attribute_identifier - string passed directly to nosetests as '-A'. - verbose : int, optional - Verbosity value for benchmark outputs, in the range 1-10. Default is 1. - extra_argv : list, optional - List with any extra arguments to pass to nosetests. - - Returns - ------- - success : bool - Returns True if running the benchmarks works, False if an error - occurred. - - Notes - ----- - Benchmarks are like tests, but have names starting with "bench" instead - of "test", and can be found under the "benchmarks" sub-directory of the - module. - - Each NumPy module exposes `bench` in its namespace to run all benchmarks - for it. - - Examples - -------- - >>> success = np.lib.bench() #doctest: +SKIP - Running benchmarks for numpy.lib - ... - using 562341 items: - unique: - 0.11 - unique1d: - 0.11 - ratio: 1.0 - nUnique: 56230 == 56230 - ... - OK - - >>> success #doctest: +SKIP - True - - """ - - print("Running benchmarks for %s" % self.package_name) - self._show_system_info() - - argv = self._test_argv(label, verbose, extra_argv) - argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep] - - # import nose or make informative error - nose = import_nose() - - # get plugin to disable doctests - from .noseclasses import Unplugger - add_plugins = [Unplugger('doctest')] - - return nose.run(argv=argv, addplugins=add_plugins) diff --git a/nipype/fixes/numpy/testing/utils.py b/nipype/fixes/numpy/testing/utils.py deleted file mode 100644 index f50cb0bd2a..0000000000 --- a/nipype/fixes/numpy/testing/utils.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -# Allow numpy fixes noseclasses to do local import of utils -from numpy.testing.utils import * diff --git a/nipype/interfaces/fsl/tests/test_dti.py b/nipype/interfaces/fsl/tests/test_dti.py index 78fa253a3d..00d8836b78 100644 --- a/nipype/interfaces/fsl/tests/test_dti.py +++ b/nipype/interfaces/fsl/tests/test_dti.py @@ -17,7 +17,7 @@ from nipype.interfaces.fsl import Info, no_fsl from nipype.interfaces.base import Undefined -import pytest, pdb +import pytest @pytest.fixture(scope="module") diff --git a/nipype/interfaces/fsl/tests/test_maths.py b/nipype/interfaces/fsl/tests/test_maths.py index a94098df2c..0d1425a345 100644 --- a/nipype/interfaces/fsl/tests/test_maths.py +++ b/nipype/interfaces/fsl/tests/test_maths.py @@ -77,23 +77,23 @@ def test_maths_base(create_files_in_directory): # Set an in file maths.inputs.in_file = "a.nii" - out_file = "a_maths%s" % out_ext + out_file = "a_maths{}".format(out_ext) # Now test the most basic command line - assert maths.cmdline == "fslmaths a.nii %s" % os.path.join(testdir, out_file) + assert maths.cmdline == "fslmaths a.nii {}".format(os.path.join(testdir, out_file)) # Now test that we can set the various data types dtypes = ["float", "char", "int", "short", "double", "input"] - int_cmdline = "fslmaths -dt %s a.nii " + os.path.join(testdir, out_file) - out_cmdline = "fslmaths a.nii " + os.path.join(testdir, out_file) + " -odt %s" - duo_cmdline = "fslmaths -dt %s a.nii " + os.path.join(testdir, out_file) + " -odt %s" + int_cmdline = "fslmaths -dt {} a.nii " + os.path.join(testdir, out_file) + out_cmdline = "fslmaths a.nii " + os.path.join(testdir, out_file) + " -odt {}" + duo_cmdline = "fslmaths -dt {} a.nii " + os.path.join(testdir, out_file) + " -odt {}" for dtype in dtypes: foo = fsl.MathsCommand(in_file="a.nii", internal_datatype=dtype) - assert foo.cmdline == int_cmdline % dtype + assert foo.cmdline == int_cmdline.format(dtype) bar = fsl.MathsCommand(in_file="a.nii", output_datatype=dtype) - assert bar.cmdline == out_cmdline % dtype + assert bar.cmdline == out_cmdline.format(dtype) foobar = fsl.MathsCommand(in_file="a.nii", internal_datatype=dtype, output_datatype=dtype) - assert foobar.cmdline == duo_cmdline % (dtype, dtype) + assert foobar.cmdline == duo_cmdline.format(dtype, dtype) # Test that we can ask for an outfile name maths.inputs.out_file = "b.nii" @@ -124,10 +124,10 @@ def test_changedt(create_files_in_directory): # Now test that we can set the various data types dtypes = ["float", "char", "int", "short", "double", "input"] - cmdline = "fslmaths a.nii b.nii -odt %s" + cmdline = "fslmaths a.nii b.nii -odt {}" for dtype in dtypes: foo = fsl.MathsCommand(in_file="a.nii", out_file="b.nii", output_datatype=dtype) - assert foo.cmdline == cmdline % dtype + assert foo.cmdline == cmdline.format(dtype) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -145,22 +145,22 @@ def test_threshold(create_files_in_directory): thresh.run() # Test the various opstrings - cmdline = "fslmaths a.nii %s b.nii" + cmdline = "fslmaths a.nii {} b.nii" for val in [0, 0., -1, -1.5, -0.5, 0.5, 3, 400, 400.5]: thresh.inputs.thresh = val - assert thresh.cmdline == cmdline % "-thr %.10f" % val + assert thresh.cmdline == cmdline.format("-thr {:.10f}".format(val)) - val = "%.10f" % 42 + val = "{:.10f}".format(42) thresh = fsl.Threshold(in_file="a.nii", out_file="b.nii", thresh=42, use_robust_range=True) - assert thresh.cmdline == cmdline % ("-thrp " + val) + assert thresh.cmdline == cmdline.format("-thrp " + val) thresh.inputs.use_nonzero_voxels = True - assert thresh.cmdline == cmdline % ("-thrP " + val) + assert thresh.cmdline == cmdline.format("-thrP " + val) thresh = fsl.Threshold(in_file="a.nii", out_file="b.nii", thresh=42, direction="above") - assert thresh.cmdline == cmdline % ("-uthr " + val) + assert thresh.cmdline == cmdline.format("-uthr " + val) thresh.inputs.use_robust_range = True - assert thresh.cmdline == cmdline % ("-uthrp " + val) + assert thresh.cmdline == cmdline.format("-uthrp " + val) thresh.inputs.use_nonzero_voxels = True - assert thresh.cmdline == cmdline % ("-uthrP " + val) + assert thresh.cmdline == cmdline.format("-uthrP " + val) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -177,14 +177,14 @@ def test_meanimage(create_files_in_directory): assert meaner.cmdline == "fslmaths a.nii -Tmean b.nii" # Test the other dimensions - cmdline = "fslmaths a.nii -%smean b.nii" + cmdline = "fslmaths a.nii -{}mean b.nii" for dim in ["X", "Y", "Z", "T"]: meaner.inputs.dimension = dim - assert meaner.cmdline == cmdline % dim + assert meaner.cmdline == cmdline.format(dim) # Test the auto naming meaner = fsl.MeanImage(in_file="a.nii") - assert meaner.cmdline == "fslmaths a.nii -Tmean %s" % os.path.join(testdir, "a_mean%s" % out_ext) + assert meaner.cmdline == "fslmaths a.nii -Tmean {}".format(os.path.join(testdir, "a_mean{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -201,16 +201,14 @@ def test_stdimage(create_files_in_directory): assert stder.cmdline == "fslmaths a.nii -Tstd b.nii" # Test the other dimensions - cmdline = "fslmaths a.nii -%sstd b.nii" + cmdline = "fslmaths a.nii -{}std b.nii" for dim in ["X","Y","Z","T"]: stder.inputs.dimension=dim - assert stder.cmdline == cmdline%dim + assert stder.cmdline == cmdline.format(dim) # Test the auto naming - stder = fsl.StdImage(in_file="a.nii") - #NOTE_dj, FAIL: this is failing (even the original version of the test with pytest) - #NOTE_dj: not sure if this should pass, it uses cmdline from interface.base.CommandLine - #assert stder.cmdline == "fslmaths a.nii -Tstd %s"%os.path.join(testdir, "a_std.nii") + stder = fsl.StdImage(in_file="a.nii", output_type='NIFTI') + assert stder.cmdline == "fslmaths a.nii -Tstd {}".format(os.path.join(testdir, "a_std.nii")) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -227,14 +225,14 @@ def test_maximage(create_files_in_directory): assert maxer.cmdline == "fslmaths a.nii -Tmax b.nii" # Test the other dimensions - cmdline = "fslmaths a.nii -%smax b.nii" + cmdline = "fslmaths a.nii -{}max b.nii" for dim in ["X", "Y", "Z", "T"]: maxer.inputs.dimension = dim - assert maxer.cmdline == cmdline % dim + assert maxer.cmdline == cmdline.format(dim) # Test the auto naming maxer = fsl.MaxImage(in_file="a.nii") - assert maxer.cmdline == "fslmaths a.nii -Tmax %s" % os.path.join(testdir, "a_max%s" % out_ext) + assert maxer.cmdline == "fslmaths a.nii -Tmax {}".format(os.path.join(testdir, "a_max{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -252,17 +250,17 @@ def test_smooth(create_files_in_directory): smoother.run() # Test smoothing kernels - cmdline = "fslmaths a.nii -s %.5f b.nii" + cmdline = "fslmaths a.nii -s {:.5f} b.nii" for val in [0, 1., 1, 25, 0.5, 8 / 3.]: smoother = fsl.IsotropicSmooth(in_file="a.nii", out_file="b.nii", sigma=val) - assert smoother.cmdline == cmdline % val + assert smoother.cmdline == cmdline.format(val) smoother = fsl.IsotropicSmooth(in_file="a.nii", out_file="b.nii", fwhm=val) val = float(val) / np.sqrt(8 * np.log(2)) - assert smoother.cmdline == cmdline % val + assert smoother.cmdline == cmdline.format(val) # Test automatic naming smoother = fsl.IsotropicSmooth(in_file="a.nii", sigma=5) - assert smoother.cmdline == "fslmaths a.nii -s %.5f %s" % (5, os.path.join(testdir, "a_smooth%s" % out_ext)) + assert smoother.cmdline == "fslmaths a.nii -s {:.5f} {}".format(5, os.path.join(testdir, "a_smooth{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -285,7 +283,7 @@ def test_mask(create_files_in_directory): # Test auto name generation masker = fsl.ApplyMask(in_file="a.nii", mask_file="b.nii") - assert masker.cmdline == "fslmaths a.nii -mas b.nii " + os.path.join(testdir, "a_masked%s" % out_ext) + assert masker.cmdline == "fslmaths a.nii -mas b.nii " + os.path.join(testdir, "a_masked{}".format(out_ext)) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -306,14 +304,14 @@ def test_dilation(create_files_in_directory): for op in ["mean", "modal", "max"]: cv = dict(mean="M", modal="D", max="F") diller.inputs.operation = op - assert diller.cmdline == "fslmaths a.nii -dil%s b.nii" % cv[op] + assert diller.cmdline == "fslmaths a.nii -dil{} b.nii".format(cv[op]) # Now test the different kernel options for k in ["3D", "2D", "box", "boxv", "gauss", "sphere"]: for size in [1, 1.5, 5]: diller.inputs.kernel_shape = k diller.inputs.kernel_size = size - assert diller.cmdline == "fslmaths a.nii -kernel %s %.4f -dilF b.nii" % (k, size) + assert diller.cmdline == "fslmaths a.nii -kernel {} {:.4f} -dilF b.nii".format(k, size) # Test that we can use a file kernel f = open("kernel.txt", "w").close() @@ -325,7 +323,7 @@ def test_dilation(create_files_in_directory): # Test that we don't need to request an out name dil = fsl.DilateImage(in_file="a.nii", operation="max") - assert dil.cmdline == "fslmaths a.nii -dilF %s" % os.path.join(testdir, "a_dil%s" % out_ext) + assert dil.cmdline == "fslmaths a.nii -dilF {}".format(os.path.join(testdir, "a_dil{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -347,7 +345,7 @@ def test_erosion(create_files_in_directory): # Test that we don't need to request an out name erode = fsl.ErodeImage(in_file="a.nii") - assert erode.cmdline == "fslmaths a.nii -ero %s" % os.path.join(testdir, "a_ero%s" % out_ext) + assert erode.cmdline == "fslmaths a.nii -ero {}".format(os.path.join(testdir, "a_ero{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -367,11 +365,11 @@ def test_spatial_filter(create_files_in_directory): # Test the different operations for op in ["mean", "meanu", "median"]: filter.inputs.operation = op - assert filter.cmdline == "fslmaths a.nii -f%s b.nii" % op + assert filter.cmdline == "fslmaths a.nii -f{} b.nii".format(op) # Test that we don't need to ask for an out name filter = fsl.SpatialFilter(in_file="a.nii", operation="mean") - assert filter.cmdline == "fslmaths a.nii -fmean %s" % os.path.join(testdir, "a_filt%s" % out_ext) + assert filter.cmdline == "fslmaths a.nii -fmean {}".format(os.path.join(testdir, "a_filt{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -392,12 +390,12 @@ def test_unarymaths(create_files_in_directory): ops = ["exp", "log", "sin", "cos", "sqr", "sqrt", "recip", "abs", "bin", "index"] for op in ops: maths.inputs.operation = op - assert maths.cmdline == "fslmaths a.nii -%s b.nii" % op + assert maths.cmdline == "fslmaths a.nii -{} b.nii".format(op) # Test that we don't need to ask for an out file for op in ops: maths = fsl.UnaryMaths(in_file="a.nii", operation=op) - assert maths.cmdline == "fslmaths a.nii -%s %s" % (op, os.path.join(testdir, "a_%s%s" % (op, out_ext))) + assert maths.cmdline == "fslmaths a.nii -{} {}".format(op, os.path.join(testdir, "a_{}{}".format(op, out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -422,15 +420,15 @@ def test_binarymaths(create_files_in_directory): maths = fsl.BinaryMaths(in_file="a.nii", out_file="c.nii", operation=op) if ent == "b.nii": maths.inputs.operand_file = ent - assert maths.cmdline == "fslmaths a.nii -%s b.nii c.nii" % op + assert maths.cmdline == "fslmaths a.nii -{} b.nii c.nii".format(op) else: maths.inputs.operand_value = ent - assert maths.cmdline == "fslmaths a.nii -%s %.8f c.nii" % (op, ent) + assert maths.cmdline == "fslmaths a.nii -{} {:.8f} c.nii".format(op, ent) # Test that we don't need to ask for an out file for op in ops: maths = fsl.BinaryMaths(in_file="a.nii", operation=op, operand_file="b.nii") - assert maths.cmdline == "fslmaths a.nii -%s b.nii %s" % (op, os.path.join(testdir, "a_maths%s" % out_ext)) + assert maths.cmdline == "fslmaths a.nii -{} b.nii {}".format(op, os.path.join(testdir, "a_maths{}".format(out_ext))) @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @@ -480,12 +478,12 @@ def test_tempfilt(create_files_in_directory): for win in windows: filt.inputs.highpass_sigma = win[0] filt.inputs.lowpass_sigma = win[1] - assert filt.cmdline == "fslmaths a.nii -bptf %.6f %.6f b.nii" % win + assert filt.cmdline == "fslmaths a.nii -bptf {:.6f} {:.6f} b.nii".format(win[0], win[1]) # Test that we don't need to ask for an out file filt = fsl.TemporalFilter(in_file="a.nii", highpass_sigma=64) assert filt.cmdline == \ - "fslmaths a.nii -bptf 64.000000 -1.000000 %s" % os.path.join(testdir, "a_filt%s" % out_ext) + "fslmaths a.nii -bptf 64.000000 -1.000000 {}".format(os.path.join(testdir, "a_filt{}".format(out_ext))) diff --git a/nipype/interfaces/tests/test_base.py b/nipype/interfaces/tests/test_base.py index 81c6ab1368..b4d45c47f4 100644 --- a/nipype/interfaces/tests/test_base.py +++ b/nipype/interfaces/tests/test_base.py @@ -156,15 +156,6 @@ class DeprecationSpec1(nib.TraitedSpec): with pytest.raises(nib.TraitError): set_foo() assert len(w) == 0, 'no warnings, just errors' - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always', '', UserWarning) - - class DeprecationSpec1numeric(nib.TraitedSpec): - foo = nib.traits.Int(deprecated='0.1') - spec_instance = DeprecationSpec1numeric() - set_foo = lambda: setattr(spec_instance, 'foo', 1) - with pytest.raises(nib.TraitError): set_foo() - assert len(w) == 0, 'no warnings, just errors' with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', '', UserWarning) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index dbc1fe6ac7..75eb323c4b 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -241,6 +241,7 @@ def test_datasink_to_s3(dummy_input, tmpdir): # Test AWS creds read from env vars +@pytest.mark.skipif(noboto3 or not fakes3, reason="boto3 or fakes3 library is not available") def test_aws_keys_from_env(): ''' Function to ensure the DataSink can successfully read in AWS diff --git a/tools/nipype_nightly.py b/tools/nipype_nightly.py deleted file mode 100644 index 9f647e903f..0000000000 --- a/tools/nipype_nightly.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python - -"""Simple script to update the trunk nightly, build the docs and push -to sourceforge. -""" - -from __future__ import print_function -from __future__ import unicode_literals -from builtins import open -import os -import sys -import subprocess - -dirname = '/home/cburns/src/nipy-sf/nipype/trunk/' - - -def run_cmd(cmd): - print(cmd) - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=os.environ, - shell=True) - output, error = proc.communicate() - returncode = proc.returncode - if returncode: - msg = 'Running cmd: %s\n Error: %s' % (cmd, error) - raise Exception(msg) - print(output) - - -def update_repos(): - """Update svn repository.""" - os.chdir(dirname) - cmd = 'svn update' - run_cmd(cmd) - - -def build_docs(): - """Build the sphinx documentation.""" - os.chdir(os.path.join(dirname, 'doc')) - cmd = 'make html' - run_cmd(cmd) - - -def push_to_sf(): - """Push documentation to sourceforge.""" - os.chdir(dirname + 'doc') - cmd = 'make sf_cburns' - run_cmd(cmd) - - -def setup_paths(): - # Cron has no PYTHONPATH defined, so we need to add the paths to - # all libraries we need. - pkg_path = '/home/cburns/local/lib/python2.6/site-packages/' - pkg_path_64 = '/home/cburns/local/lib64/python2.6/site-packages/' - - # Add the current directory to path - sys.path.insert(0, os.curdir) - # Add our local path, where we install nipype, to sys.path - sys.path.insert(0, pkg_path) - # Needed to add this to my path at one point otherwise import of - # apigen failed. - # sys.path.insert(2, '/home/cburns/src/nipy-sf/nipype/trunk/tools') - - # Add networkx, twisted, zope.interface and foolscap. - # Basically we need to add all the packages we need that are - # installed via setyptools, since it's uses the .pth files for - # this. - nx_path = os.path.join(pkg_path, 'networkx-0.99-py2.6.egg') - sys.path.insert(2, nx_path) - twisted_path = os.path.join(pkg_path_64, - 'Twisted-8.2.0-py2.6-linux-x86_64.egg') - sys.path.insert(2, twisted_path) - zope_path = os.path.join(pkg_path_64, - 'zope.interface-3.5.2-py2.6-linux-x86_64.egg') - sys.path.insert(2, zope_path) - foolscap_path = os.path.join(pkg_path, - 'foolscap-0.2.9-py2.6.egg') - sys.path.insert(2, foolscap_path) - - # Define our PYTHONPATH variable - os.environ['PYTHONPATH'] = ':'.join(sys.path) - -if __name__ == '__main__': - setup_paths() - prev_dir = os.path.abspath(os.curdir) - update_repos() - build_docs() - # push_to_sf() - os.chdir(prev_dir) diff --git a/tools/report_coverage.py b/tools/report_coverage.py deleted file mode 100644 index d02e2c7851..0000000000 --- a/tools/report_coverage.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -from __future__ import unicode_literals -from builtins import open -import subprocess - - -def run_tests(cmd): - proc = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True) - stdout, stderr = proc.communicate() - if proc.returncode: - msg = 'Running cmd: %s\n Error: %s' % (cmd, error) - raise Exception(msg) - # Nose returns the output in stderr - return stderr - - -def grab_coverage(output): - """Grab coverage lines from nose output.""" - output = output.split('\n') - covout = [] - header = None - tcount = None - for line in output: - if line.startswith('nipype.interfaces.') or \ - line.startswith('nipype.pipeline.') or \ - line.startswith('nipype.utils.'): - # Remove the Missing lines, too noisy - percent_index = line.find('%') - percent_index += 1 - covout.append(line[:percent_index]) - if line.startswith('Name '): - header = line - if line.startswith('Ran '): - tcount = line - covout.insert(0, header) - covout.insert(1, '-' * 70) - covout.append('-' * 70) - covout.append(tcount) - return '\n'.join(covout) - - -def main(): - cmd = 'nosetests --with-coverage --cover-package=nipype' - print('From current directory, running cmd:') - print(cmd, '\n') - output = run_tests(cmd) - report = grab_coverage(output) - print(report) - -main() diff --git a/tools/setup.py b/tools/setup.py deleted file mode 100644 index fba34de078..0000000000 --- a/tools/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup - -setup(name='Nipype Tools', - version='0.1', - description='Utilities used in nipype development', - author='Nipype Developers', - author_email='nipy-devel@neuroimaging.scipy.org', - url='http://nipy.sourceforge.net', - scripts=['./nipype_nightly.py', './report_coverage.py'] - )