@@ -1860,7 +1860,19 @@ def _list_outputs(self):
18601860
18611861class JSONFileSinkInputSpec (DynamicTraitedSpec , BaseInterfaceInputSpec ):
18621862 out_file = File (desc = 'JSON sink file' )
1863- in_dict = traits .Dict (desc = 'input JSON dictionary' )
1863+ in_dict = traits .Dict (value = {}, usedefault = True ,
1864+ desc = 'input JSON dictionary' )
1865+ _outputs = traits .Dict (value = {}, usedefault = True )
1866+
1867+ def __setattr__ (self , key , value ):
1868+ if key not in self .copyable_trait_names ():
1869+ if not isdefined (value ):
1870+ super (JSONFileSinkInputSpec , self ).__setattr__ (key , value )
1871+ self ._outputs [key ] = value
1872+ else :
1873+ if key in self ._outputs :
1874+ self ._outputs [key ] = value
1875+ super (JSONFileSinkInputSpec , self ).__setattr__ (key , value )
18641876
18651877
18661878class JSONFileSinkOutputSpec (TraitedSpec ):
@@ -1869,7 +1881,10 @@ class JSONFileSinkOutputSpec(TraitedSpec):
18691881
18701882class JSONFileSink (IOBase ):
18711883
1872- """ Very simple frontend for storing values into a JSON file.
1884+ """
1885+ Very simple frontend for storing values into a JSON file.
1886+ Entries already existing in in_dict will be overridden by matching
1887+ entries dynamically added as inputs.
18731888
18741889 .. warning::
18751890
@@ -1896,34 +1911,52 @@ class JSONFileSink(IOBase):
18961911 input_spec = JSONFileSinkInputSpec
18971912 output_spec = JSONFileSinkOutputSpec
18981913
1899- def __init__ (self , input_names = [], ** inputs ):
1914+ def __init__ (self , infields = [], force_run = True , ** inputs ):
19001915 super (JSONFileSink , self ).__init__ (** inputs )
1901- self ._input_names = filename_to_list (input_names )
1902- add_traits (self .inputs , [name for name in self ._input_names ])
1916+ self ._input_names = infields
1917+
1918+ undefined_traits = {}
1919+ for key in infields :
1920+ self .inputs .add_trait (key , traits .Any )
1921+ self .inputs ._outputs [key ] = Undefined
1922+ undefined_traits [key ] = Undefined
1923+ self .inputs .trait_set (trait_change_notify = False , ** undefined_traits )
1924+
1925+ if force_run :
1926+ self ._always_run = True
1927+
1928+ def _process_name (self , name , val ):
1929+ if '.' in name :
1930+ newkeys = name .split ('.' )
1931+ name = newkeys .pop (0 )
1932+ nested_dict = {newkeys .pop (): val }
1933+
1934+ for nk in reversed (newkeys ):
1935+ nested_dict = {nk : nested_dict }
1936+ val = nested_dict
1937+
1938+ return name , val
19031939
19041940 def _list_outputs (self ):
19051941 import json
19061942 import os .path as op
1943+
19071944 if not isdefined (self .inputs .out_file ):
19081945 out_file = op .abspath ('datasink.json' )
19091946 else :
19101947 out_file = self .inputs .out_file
19111948
1912- out_dict = dict ()
1949+ out_dict = self . inputs . in_dict
19131950
1914- if isdefined (self .inputs .in_dict ):
1915- if isinstance (self .inputs .in_dict , dict ):
1916- out_dict = self .inputs .in_dict
1917- else :
1918- for name in self ._input_names :
1919- val = getattr (self .inputs , name )
1920- val = val if isdefined (val ) else 'undefined'
1921- out_dict [name ] = val
1951+ # Overwrite in_dict entries automatically
1952+ for key , val in self .inputs ._outputs .items ():
1953+ if not isdefined (val ) or key == 'trait_added' :
1954+ continue
1955+ key , val = self ._process_name (key , val )
1956+ out_dict [key ] = val
19221957
19231958 with open (out_file , 'w' ) as f :
19241959 json .dump (out_dict , f )
19251960 outputs = self .output_spec ().get ()
19261961 outputs ['out_file' ] = out_file
19271962 return outputs
1928-
1929-
0 commit comments