From ee8815712bc7a0b4b06a3199c499973cbfb4d4fa Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 26 Sep 2019 10:03:30 -0400 Subject: [PATCH 01/23] Add "copy" trait to Rename, to allow copying instead of symlink --- nipype/interfaces/utility/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/utility/base.py b/nipype/interfaces/utility/base.py index d01a0a17b9..d6d652de25 100644 --- a/nipype/interfaces/utility/base.py +++ b/nipype/interfaces/utility/base.py @@ -213,6 +213,8 @@ class RenameInputSpec(DynamicTraitedSpec): "replacement inputs") use_fullpath = traits.Bool( False, usedefault=True, desc="Use full path as input to regex parser") + copy = traits.Bool(False, usedefault=True, desc="Whether to copy the file " + "(True) or try to symlink it (False)") class RenameOutputSpec(TraitedSpec): @@ -301,7 +303,7 @@ def _rename(self): def _run_interface(self, runtime): runtime.returncode = 0 out_file = os.path.join(runtime.cwd, self._rename()) - _ = copyfile(self.inputs.in_file, out_file) + _ = copyfile(self.inputs.in_file, out_file, copy=self.inputs.copy) self._results['out_file'] = out_file return runtime From b8d29a959a5ff4560174870cd28e8273280692e1 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 26 Sep 2019 10:48:05 -0400 Subject: [PATCH 02/23] Revert "Add "copy" trait to Rename, to allow copying instead of symlink" This reverts commit ee8815712bc7a0b4b06a3199c499973cbfb4d4fa. --- nipype/interfaces/utility/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nipype/interfaces/utility/base.py b/nipype/interfaces/utility/base.py index d6d652de25..d01a0a17b9 100644 --- a/nipype/interfaces/utility/base.py +++ b/nipype/interfaces/utility/base.py @@ -213,8 +213,6 @@ class RenameInputSpec(DynamicTraitedSpec): "replacement inputs") use_fullpath = traits.Bool( False, usedefault=True, desc="Use full path as input to regex parser") - copy = traits.Bool(False, usedefault=True, desc="Whether to copy the file " - "(True) or try to symlink it (False)") class RenameOutputSpec(TraitedSpec): @@ -303,7 +301,7 @@ def _rename(self): def _run_interface(self, runtime): runtime.returncode = 0 out_file = os.path.join(runtime.cwd, self._rename()) - _ = copyfile(self.inputs.in_file, out_file, copy=self.inputs.copy) + _ = copyfile(self.inputs.in_file, out_file) self._results['out_file'] = out_file return runtime From 1b083f10028456e6bbee6bf18b770e77e1a77f0c Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 26 Sep 2019 11:16:02 -0400 Subject: [PATCH 03/23] create ExportFile interface --- nipype/interfaces/io.py | 31 ++++++++++++++++++++++++++++++ nipype/interfaces/tests/test_io.py | 23 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index c409d4e78a..d405cf7150 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -28,6 +28,7 @@ import tempfile from os.path import join, dirname from warnings import warn +import errno from .. import config, logging from ..utils.filemanip import ( @@ -2863,3 +2864,33 @@ def _list_outputs(self): def _add_output_traits(self, base): return add_traits(base, list(self.inputs.output_query.keys())) + + +class ExportFileInputSpec(BaseInterfaceInputSpec): + in_file = File(exists=True, desc='Input file name') + out_file = File(exists=False, desc='Output file name') + check_extension = traits.Bool(False, desc='Ensure that the input and output file extensions match') + clobber = traits.Bool(False, desc='Permit overwriting existing files') + + +class ExportFileOutputSpec(TraitedSpec): + out_file = File(exists=True, desc='Output file name') + + +class ExportFile(BaseInterface): + input_spec = ExportFileInputSpec + output_spec = ExportFileOutputSpec + + def _run_interface(self, runtime): + if not self.inputs.clobber and op.exists(self.inputs.out_file): + raise FileExistsError(errno.EEXIST, f'File {self.inputs.out_file} exists') + if (self.inputs.check_extension and + op.splitext(self.inputs.in_file)[1] != op.splitext(self.inputs.out_file)[1]): + raise RuntimeError(f'{self.inputs.in_file} and {self.inputs.out_file} have different extensions') + shutil.copy(str(self.inputs.in_file), str(self.inputs.out_file)) + return runtime + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs['out_file'] = self.inputs.out_file + return outputs diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index 4420e4a49c..4dd408c36d 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -680,3 +680,26 @@ def _mock_get_ssh_client(self): .check(file=True, exists=True)) # exists? old_cwd.chdir() + + +def test_ExportFile(tmp_path): + testin = tmp_path / 'in.txt' + testin.write_text('test string') + i = nio.ExportFile() + i.inputs.in_file = testin + i.inputs.out_file = tmp_path / 'out.tsv' + i.inputs.check_extension = True + with pytest.raises(RuntimeError): + i.run() + i.inputs.check_extension = False + i.run() + assert (tmp_path / 'out.tsv').read_text() == 'test string' + i.inputs.out_file = tmp_path / 'out.txt' + i.inputs.check_extension = True + i.run() + assert (tmp_path / 'out.txt').read_text() == 'test string' + with pytest.raises(FileExistsError): + i.run() + i.inputs.clobber = True + i.run() + assert (tmp_path / 'out.txt').read_text() == 'test string' From 9bd195ae8f558189a113931591b8972c5225498a Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 1 Oct 2019 16:21:42 -0400 Subject: [PATCH 04/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index d405cf7150..b8e4540974 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2870,7 +2870,7 @@ class ExportFileInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, desc='Input file name') out_file = File(exists=False, desc='Output file name') check_extension = traits.Bool(False, desc='Ensure that the input and output file extensions match') - clobber = traits.Bool(False, desc='Permit overwriting existing files') + clobber = traits.Bool(desc='Permit overwriting existing files') class ExportFileOutputSpec(TraitedSpec): From c870166f19b2d31d5403eb5880d0a2dbec51c63b Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 1 Oct 2019 16:21:53 -0400 Subject: [PATCH 05/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index b8e4540974..51b1422736 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2867,7 +2867,7 @@ def _add_output_traits(self, base): class ExportFileInputSpec(BaseInterfaceInputSpec): - in_file = File(exists=True, desc='Input file name') + in_file = File(exists=True, mandatory=True, desc='Input file name') out_file = File(exists=False, desc='Output file name') check_extension = traits.Bool(False, desc='Ensure that the input and output file extensions match') clobber = traits.Bool(desc='Permit overwriting existing files') From 0d18f98a3132916e4a66f70075616c221eca0fdd Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 1 Oct 2019 16:21:59 -0400 Subject: [PATCH 06/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 51b1422736..506c6dd768 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2868,7 +2868,7 @@ def _add_output_traits(self, base): class ExportFileInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='Input file name') - out_file = File(exists=False, desc='Output file name') + out_file = File(mandatory=True, desc='Output file name') check_extension = traits.Bool(False, desc='Ensure that the input and output file extensions match') clobber = traits.Bool(desc='Permit overwriting existing files') From abe83ddad6c068cad5f9952002f65abed1f12a01 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 1 Oct 2019 16:23:31 -0400 Subject: [PATCH 07/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 506c6dd768..d3ee34c86d 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2883,7 +2883,7 @@ class ExportFile(BaseInterface): def _run_interface(self, runtime): if not self.inputs.clobber and op.exists(self.inputs.out_file): - raise FileExistsError(errno.EEXIST, f'File {self.inputs.out_file} exists') + raise FileExistsError(errno.EEXIST, 'File %s exists' % self.inputs.out_file) if (self.inputs.check_extension and op.splitext(self.inputs.in_file)[1] != op.splitext(self.inputs.out_file)[1]): raise RuntimeError(f'{self.inputs.in_file} and {self.inputs.out_file} have different extensions') From cba09b2c0a4f758034869348aa153cfc7da077ed Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 1 Oct 2019 16:37:30 -0400 Subject: [PATCH 08/23] Apply @effigies suggestions --- nipype/interfaces/io.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index d3ee34c86d..f752f09252 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -33,12 +33,12 @@ from .. import config, logging from ..utils.filemanip import ( copyfile, simplify_list, ensure_list, - get_related_files) + get_related_files, split_filename) from ..utils.misc import human_order_sorted, str2bool from .base import ( TraitedSpec, traits, Str, File, Directory, BaseInterface, InputMultiPath, isdefined, OutputMultiPath, DynamicTraitedSpec, Undefined, BaseInterfaceInputSpec, - LibraryBaseInterface) + LibraryBaseInterface, SimpleInterface) iflogger = logging.getLogger('nipype.interface') @@ -2869,7 +2869,7 @@ def _add_output_traits(self, base): class ExportFileInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='Input file name') out_file = File(mandatory=True, desc='Output file name') - check_extension = traits.Bool(False, desc='Ensure that the input and output file extensions match') + check_extension = traits.Bool(True, desc='Ensure that the input and output file extensions match') clobber = traits.Bool(desc='Permit overwriting existing files') @@ -2877,20 +2877,18 @@ class ExportFileOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Output file name') -class ExportFile(BaseInterface): +class ExportFile(SimpleInterface): input_spec = ExportFileInputSpec output_spec = ExportFileOutputSpec def _run_interface(self, runtime): if not self.inputs.clobber and op.exists(self.inputs.out_file): raise FileExistsError(errno.EEXIST, 'File %s exists' % self.inputs.out_file) + if not op.isabs(self.inputs.out_file): + raise ValueError('Out_file must be an absolute path.') if (self.inputs.check_extension and - op.splitext(self.inputs.in_file)[1] != op.splitext(self.inputs.out_file)[1]): - raise RuntimeError(f'{self.inputs.in_file} and {self.inputs.out_file} have different extensions') + split_filename(self.inputs.in_file)[2] != split_filename(self.inputs.out_file)[2]): + raise RuntimeError('%s and %s have different extensions' % (self.inputs.in_file, self.inputs.out_file)) shutil.copy(str(self.inputs.in_file), str(self.inputs.out_file)) + self._results['out_file'] = self.inputs.out_file return runtime - - def _list_outputs(self): - outputs = self.output_spec().get() - outputs['out_file'] = self.inputs.out_file - return outputs From edcb73cb931da3038d687121f56d801e3e066cba Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 8 Oct 2019 10:37:18 -0400 Subject: [PATCH 09/23] add FileExistsError to filemanipy for python 2 support --- nipype/interfaces/io.py | 6 +++--- nipype/utils/filemanip.py | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index f752f09252..ebf2ca5efc 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -28,12 +28,12 @@ import tempfile from os.path import join, dirname from warnings import warn -import errno from .. import config, logging from ..utils.filemanip import ( copyfile, simplify_list, ensure_list, - get_related_files, split_filename) + get_related_files, split_filename, + FileExistsError) from ..utils.misc import human_order_sorted, str2bool from .base import ( TraitedSpec, traits, Str, File, Directory, BaseInterface, InputMultiPath, @@ -2883,7 +2883,7 @@ class ExportFile(SimpleInterface): def _run_interface(self, runtime): if not self.inputs.clobber and op.exists(self.inputs.out_file): - raise FileExistsError(errno.EEXIST, 'File %s exists' % self.inputs.out_file) + raise FileExistsError(self.inputs.out_file) if not op.isabs(self.inputs.out_file): raise ValueError('Out_file must be an absolute path.') if (self.inputs.check_extension and diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 1cdd1e9676..583357c148 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -51,6 +51,14 @@ def __init__(self, path): super(FileNotFoundError, self).__init__( 2, 'No such file or directory', '%s' % path) + class FileExistsError(OSError): # noqa + """Defines the exception for Python 2.""" + + def __init__(self, path): + """Initialize the exception.""" + super(FileExistsError, self).__init__( + 17, 'File or directory exists', '%s' % path) + USING_PATHLIB2 = False try: From b25c9c3328e9f2c49383734fbd85aa16d970d54e Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 8 Oct 2019 17:15:04 -0400 Subject: [PATCH 10/23] bugfix. actually import FileExistsError --- nipype/utils/filemanip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 1e134a3333..d846ce4bca 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -41,7 +41,7 @@ PY3 = sys.version_info[0] >= 3 try: - from builtins import FileNotFoundError + from builtins import FileNotFoundError, FileExistsError except ImportError: # PY27 class FileNotFoundError(OSError): # noqa """Defines the exception for Python 2.""" From 006cdcfed7704fd553a236d74e7faa75793884a9 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Wed, 9 Oct 2019 09:46:39 -0400 Subject: [PATCH 11/23] import FileExistsError in test --- nipype/interfaces/tests/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index 5013f04942..1b83f1c3c6 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -20,7 +20,7 @@ import nipype.interfaces.io as nio from nipype.interfaces.base.traits_extension import isdefined from nipype.interfaces.base import Undefined, TraitError -from nipype.utils.filemanip import dist_is_editable +from nipype.utils.filemanip import dist_is_editable, FileExistsError # Check for boto noboto = False From 5737d212a277efcbe0a36226d0f2e59a98c81ebc Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Wed, 9 Oct 2019 11:14:13 -0400 Subject: [PATCH 12/23] Update nipype/interfaces/tests/test_io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/tests/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index 1b83f1c3c6..bd1af89c1d 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -687,7 +687,7 @@ def test_ExportFile(tmp_path): testin.write_text('test string') i = nio.ExportFile() i.inputs.in_file = testin - i.inputs.out_file = tmp_path / 'out.tsv' + i.inputs.out_file = str(tmp_path / 'out.tsv') i.inputs.check_extension = True with pytest.raises(RuntimeError): i.run() From 47bb8e8376d1847fc377d41ddf82a1911227ed79 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Wed, 9 Oct 2019 11:14:22 -0400 Subject: [PATCH 13/23] Update nipype/interfaces/tests/test_io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/tests/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index bd1af89c1d..de0452d0a0 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -686,7 +686,7 @@ def test_ExportFile(tmp_path): testin = tmp_path / 'in.txt' testin.write_text('test string') i = nio.ExportFile() - i.inputs.in_file = testin + i.inputs.in_file = str(testin) i.inputs.out_file = str(tmp_path / 'out.tsv') i.inputs.check_extension = True with pytest.raises(RuntimeError): From 1ba9ca1480354f744cb97a76e343303a4254e305 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Wed, 9 Oct 2019 14:26:40 -0400 Subject: [PATCH 14/23] add docstring to ExportFile --- nipype/interfaces/io.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 6d2ac1d970..0eaa2f9726 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2878,6 +2878,27 @@ class ExportFileOutputSpec(TraitedSpec): class ExportFile(SimpleInterface): + """Copy in_file to out_file. + + This interface copies an input file to a named output file. + This is useful to save files to a specified location + (as opposed to using DataSink). + + Examples + -------- + + A trivial example that copies temporary_file.nii.gz + to sub1_out.nii.gz. (A more realistic example would set + in_file as the output of another Node.) + + >>> from nipype.interfaces.io import ExportFile + >>> import os.path as op + >>> ef = Node(ExportFile(), "export") + >>> ef.inputs.in_file = "temporary_file.nii.gz" + >>> ef.inputs.out_file = op.abspath("output_folder/sub1_out.nii.gz") + >>> ef.run() + + """ input_spec = ExportFileInputSpec output_spec = ExportFileOutputSpec From ec023bfb1906ea6378593a7323e567e0f1e080ec Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 17 Oct 2019 16:45:25 -0400 Subject: [PATCH 15/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 0eaa2f9726..8dd59d60dc 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2878,7 +2878,7 @@ class ExportFileOutputSpec(TraitedSpec): class ExportFile(SimpleInterface): - """Copy in_file to out_file. + """ Export a file to an absolute path This interface copies an input file to a named output file. This is useful to save files to a specified location From 1e0d7a1db2390e14f61a605fa8f27ee0b3d0fbd0 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 17 Oct 2019 16:45:36 -0400 Subject: [PATCH 16/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 8dd59d60dc..dd66d1e3dd 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2881,7 +2881,7 @@ class ExportFile(SimpleInterface): """ Export a file to an absolute path This interface copies an input file to a named output file. - This is useful to save files to a specified location + This is useful to save individual files to a specific location, (as opposed to using DataSink). Examples From 4246b029dd2e61b51ec56b609917da29e21834bd Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 17 Oct 2019 16:45:45 -0400 Subject: [PATCH 17/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index dd66d1e3dd..fde8b84015 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2882,7 +2882,7 @@ class ExportFile(SimpleInterface): This interface copies an input file to a named output file. This is useful to save individual files to a specific location, - (as opposed to using DataSink). + instead of more flexible interfaces like DataSink. Examples -------- From fe3dd0754338d69904a6e7e1882f63419d1dd2bd Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 17 Oct 2019 16:46:10 -0400 Subject: [PATCH 18/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index fde8b84015..51b0b31904 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2893,7 +2893,7 @@ class ExportFile(SimpleInterface): >>> from nipype.interfaces.io import ExportFile >>> import os.path as op - >>> ef = Node(ExportFile(), "export") + >>> ef = ExportFile() >>> ef.inputs.in_file = "temporary_file.nii.gz" >>> ef.inputs.out_file = op.abspath("output_folder/sub1_out.nii.gz") >>> ef.run() From 7ed854ff2abcf76a68b3e2b40124ea3342aa0903 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Thu, 17 Oct 2019 16:55:31 -0400 Subject: [PATCH 19/23] bugfixes in docstring --- nipype/interfaces/io.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 51b0b31904..801bc73d71 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2887,14 +2887,11 @@ class ExportFile(SimpleInterface): Examples -------- - A trivial example that copies temporary_file.nii.gz - to sub1_out.nii.gz. (A more realistic example would set - in_file as the output of another Node.) - >>> from nipype.interfaces.io import ExportFile >>> import os.path as op >>> ef = ExportFile() - >>> ef.inputs.in_file = "temporary_file.nii.gz" + >>> ef.inputs.in_file = "T1.nii.gz" + >>> os.mkdir("output_folder") >>> ef.inputs.out_file = op.abspath("output_folder/sub1_out.nii.gz") >>> ef.run() From 7a3c7f61243bda06338b68907b80a66efbb85609 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Mon, 21 Oct 2019 14:27:55 -0400 Subject: [PATCH 20/23] Update nipype/interfaces/io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 801bc73d71..46446f1a1c 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2893,7 +2893,7 @@ class ExportFile(SimpleInterface): >>> ef.inputs.in_file = "T1.nii.gz" >>> os.mkdir("output_folder") >>> ef.inputs.out_file = op.abspath("output_folder/sub1_out.nii.gz") - >>> ef.run() + >>> res = ef.run() """ input_spec = ExportFileInputSpec From 1c26d1d0a31f0053d75643048999562e776ff9ef Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Mon, 21 Oct 2019 14:28:02 -0400 Subject: [PATCH 21/23] Update nipype/interfaces/tests/test_io.py Co-Authored-By: Chris Markiewicz --- nipype/interfaces/tests/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index de0452d0a0..9cb7e05075 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -694,7 +694,7 @@ def test_ExportFile(tmp_path): i.inputs.check_extension = False i.run() assert (tmp_path / 'out.tsv').read_text() == 'test string' - i.inputs.out_file = tmp_path / 'out.txt' + i.inputs.out_file = str(tmp_path / 'out.txt') i.inputs.check_extension = True i.run() assert (tmp_path / 'out.txt').read_text() == 'test string' From a23e16da25b7d7e664cfd5702b5143fd6d80a4be Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Mon, 21 Oct 2019 14:30:08 -0400 Subject: [PATCH 22/23] Add @effigies suggestion --- nipype/interfaces/io.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 46446f1a1c..556d85db4d 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -2894,6 +2894,8 @@ class ExportFile(SimpleInterface): >>> os.mkdir("output_folder") >>> ef.inputs.out_file = op.abspath("output_folder/sub1_out.nii.gz") >>> res = ef.run() + >>> os.path.exists(res.outputs.out_file) + True """ input_spec = ExportFileInputSpec From 3695d36e1e66a57089e6b7ecfc402a9d2fe2c925 Mon Sep 17 00:00:00 2001 From: Steven Tilley Date: Tue, 22 Oct 2019 10:49:43 -0400 Subject: [PATCH 23/23] add test_auto_ExportFile.py --- .../interfaces/tests/test_auto_ExportFile.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 nipype/interfaces/tests/test_auto_ExportFile.py diff --git a/nipype/interfaces/tests/test_auto_ExportFile.py b/nipype/interfaces/tests/test_auto_ExportFile.py new file mode 100644 index 0000000000..335fe41372 --- /dev/null +++ b/nipype/interfaces/tests/test_auto_ExportFile.py @@ -0,0 +1,30 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from __future__ import unicode_literals +from ..io import ExportFile + + +def test_ExportFile_inputs(): + input_map = dict( + check_extension=dict(), + clobber=dict(), + in_file=dict( + extensions=None, + mandatory=True, + ), + out_file=dict( + extensions=None, + mandatory=True, + ), + ) + inputs = ExportFile.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_ExportFile_outputs(): + output_map = dict(out_file=dict(extensions=None, ), ) + outputs = ExportFile.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value