2
2
# vi: set ft=python sts=4 ts=4 sw=4 et:
3
3
import os
4
4
import re
5
+ from cPickle import dumps , loads
5
6
import numpy as np
6
7
import nibabel as nb
7
8
11
12
InputMultiPath , BaseInterface , BaseInterfaceInputSpec )
12
13
from nipype .interfaces .io import IOBase , add_traits
13
14
from nipype .testing import assert_equal
14
- from nipype .utils .misc import getsource , create_function_from_source , dumps
15
+ from nipype .utils .misc import getsource , create_function_from_source
15
16
16
17
17
18
class IdentityInterface (IOBase ):
@@ -335,7 +336,8 @@ class Function(IOBase):
335
336
input_spec = FunctionInputSpec
336
337
output_spec = DynamicTraitedSpec
337
338
338
- def __init__ (self , input_names , output_names , function = None , ** inputs ):
339
+ def __init__ (self , input_names , output_names , function = None , imports = None ,
340
+ ** inputs ):
339
341
"""
340
342
341
343
Parameters
@@ -344,7 +346,15 @@ def __init__(self, input_names, output_names, function=None, **inputs):
344
346
input_names: single str or list
345
347
names corresponding to function inputs
346
348
output_names: single str or list
347
- names corresponding to function outputs. has to match the number of outputs
349
+ names corresponding to function outputs.
350
+ has to match the number of outputs
351
+ function : callable
352
+ callable python object. must be able to execute in an
353
+ isolated namespace (possibly in concert with the ``imports``
354
+ parameter)
355
+ imports : list of strings
356
+ list of import statements that allow the function to execute
357
+ in an otherwise empty namespace
348
358
"""
349
359
350
360
super (Function , self ).__init__ (** inputs )
@@ -354,15 +364,18 @@ def __init__(self, input_names, output_names, function=None, **inputs):
354
364
self .inputs .function_str = getsource (function )
355
365
except IOError :
356
366
raise Exception ('Interface Function does not accept ' \
357
- 'function objects defined interactively in a python session' )
367
+ 'function objects defined interactively ' \
368
+ 'in a python session' )
358
369
elif isinstance (function , str ):
359
370
self .inputs .function_str = dumps (function )
360
371
else :
361
372
raise Exception ('Unknown type of function' )
362
- self .inputs .on_trait_change (self ._set_function_string , 'function_str' )
373
+ self .inputs .on_trait_change (self ._set_function_string ,
374
+ 'function_str' )
363
375
self ._input_names = filename_to_list (input_names )
364
376
self ._output_names = filename_to_list (output_names )
365
377
add_traits (self .inputs , [name for name in self ._input_names ])
378
+ self .imports = imports
366
379
self ._out = {}
367
380
for name in self ._output_names :
368
381
self ._out [name ] = None
@@ -373,7 +386,8 @@ def _set_function_string(self, obj, name, old, new):
373
386
function_source = getsource (new )
374
387
elif isinstance (new , str ):
375
388
function_source = dumps (new )
376
- self .inputs .trait_set (trait_change_notify = False , ** {'%s' % name : function_source })
389
+ self .inputs .trait_set (trait_change_notify = False ,
390
+ ** {'%s' % name : function_source })
377
391
378
392
def _add_output_traits (self , base ):
379
393
undefined_traits = {}
@@ -384,7 +398,8 @@ def _add_output_traits(self, base):
384
398
return base
385
399
386
400
def _run_interface (self , runtime ):
387
- function_handle = create_function_from_source (self .inputs .function_str )
401
+ function_handle = create_function_from_source (self .inputs .function_str ,
402
+ self .imports )
388
403
389
404
args = {}
390
405
for name in self ._input_names :
0 commit comments