3434from ..interfaces .base import (BaseInterface , traits , TraitedSpec , File ,
3535 InputMultiPath , OutputMultiPath ,
3636 BaseInterfaceInputSpec , isdefined ,
37- DynamicTraitedSpec )
37+ DynamicTraitedSpec , Undefined )
3838from nipype .utils .filemanip import fname_presuffix , split_filename
3939iflogger = logging .getLogger ('interface' )
4040
@@ -785,7 +785,8 @@ def _list_outputs(self):
785785
786786
787787class AddCSVRowInputSpec (DynamicTraitedSpec , BaseInterfaceInputSpec ):
788- in_file = traits .File (mandatory = True , desc = 'Input comma-separated value (CSV) files' )
788+ in_file = traits .File (mandatory = True ,
789+ desc = 'Input comma-separated value (CSV) files' )
789790 _outputs = traits .Dict (traits .Any , value = {}, usedefault = True )
790791
791792 def __setattr__ (self , key , value ):
@@ -804,13 +805,15 @@ class AddCSVRowOutputSpec(TraitedSpec):
804805
805806
806807class AddCSVRow (BaseInterface ):
808+
807809 """Simple interface to add an extra row to a csv file
808810
809811 .. note:: Requires `pandas <http://pandas.pydata.org/>`_
810812
811813 .. warning:: Multi-platform thread-safe execution is possible with
812- `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please recall that (1)
813- this module is alpha software; and (2) it should be installed for thread-safe writing.
814+ `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please
815+ recall that (1) this module is alpha software; and (2) it should be
816+ installed for thread-safe writing.
814817 If lockfile is not installed, then the interface is not thread-safe.
815818
816819
@@ -822,7 +825,7 @@ class AddCSVRow(BaseInterface):
822825 >>> addrow.inputs.in_file = 'scores.csv'
823826 >>> addrow.inputs.si = 0.74
824827 >>> addrow.inputs.di = 0.93
825- >>> addrow.subject_id = 'S400'
828+ >>> addrow.inputs. subject_id = 'S400'
826829 >>> addrow.inputs.list_of_values = [ 0.4, 0.7, 0.3 ]
827830 >>> addrow.run() # doctest: +SKIP
828831 """
@@ -850,22 +853,26 @@ def _run_interface(self, runtime):
850853 try :
851854 import pandas as pd
852855 except ImportError :
853- raise ImportError ('This interface requires pandas (http://pandas.pydata.org/) to run.' )
856+ raise ImportError (('This interface requires pandas '
857+ '(http://pandas.pydata.org/) to run.' ))
854858
855859 try :
856860 import lockfile as pl
857861 self ._have_lock = True
858862 except ImportError :
859- import warnings
860- warnings . warn (('Python module lockfile was not found: AddCSVRow will not be thread-safe '
861- ' in multi-processor execution' ))
863+ from warnings import warn
864+ warn (('Python module lockfile was not found: AddCSVRow will not be'
865+ ' thread-safe in multi-processor execution' ))
862866
863867 input_dict = {}
864868 for key , val in self .inputs ._outputs .items ():
865869 # expand lists to several columns
870+ if key == 'trait_added' and val in self .inputs .copyable_trait_names ():
871+ continue
872+
866873 if isinstance (val , list ):
867- for i ,v in enumerate (val ):
868- input_dict ['%s_%d' % (key ,i )]= v
874+ for i , v in enumerate (val ):
875+ input_dict ['%s_%d' % (key , i )] = v
869876 else :
870877 input_dict [key ] = val
871878
@@ -887,6 +894,13 @@ def _run_interface(self, runtime):
887894 if self ._have_lock :
888895 self ._lock .release ()
889896
897+ # Using nipype.external.portalocker this might be something like:
898+ # with pl.Lock(self.inputs.in_file, timeout=1) as fh:
899+ # if op.exists(fh):
900+ # formerdf = pd.read_csv(fh, index_col=0)
901+ # df = pd.concat([formerdf, df], ignore_index=True)
902+ # df.to_csv(fh)
903+
890904 return runtime
891905
892906 def _list_outputs (self ):
0 commit comments