Open
Description
Any interest in adding a meta-interface like the following?
class OptionalInterface(SimpleInterface):
def __init__(self, real_interface):
class input_spec(real_interface.__class__.input_spec):
pass
class output_spec(real_interface.__class__.output_spec):
pass
self._interface = real_interface
self.input_spec = input_spec
self.output_spec = output_spec
self._mandatory = [name for name, trait in input_spec.__class_traits__.items()
if trait.mandatory]
for name in self._mandatory:
trait = deepcopy(input_spec.__class_traits__[name])
trait.mandatory = False
self.input_spec.__base_traits__[name] = trait
self.input_spec.__class_traits__[name] = trait
super(OptionalInterface, self).__init__()
self.inputs.trait_set(**self._interface.inputs.get_traitsfree())
def _run_interface(self, runtime):
do_run = all(isdefined(getattr(self.inputs, trait)) for trait in self._mandatory)
if do_run:
self._interface.inputs.set(**self.inputs.get_traitsfree())
runtime = self._interface._run_interface(runtime)
self._results.update(self._interface.aggregate_outputs(runtime).get_traitsfree())
return runtime
This wraps an interface such that, if the mandatory inputs are not set, the outputs are left undefined.
I'm currently thinking of it for the purposes of inserting a validation step for an optional input to another node that always run, but it could also be chained to set up a part of a pipeline that will only execute if an input is present, but will silently pass Undefined
s otherwise.
This is an initial hack, and some of the above might not be necessary. Currently testing with the following code:
class A(SimpleInterface):
class input_spec(BaseInterfaceInputSpec):
a = traits.Int(mandatory=True)
b = traits.Int()
class output_spec(TraitedSpec):
c = traits.Int()
def _run_interface(self, runtime):
self._results['c'] = self.inputs.a + (self.inputs.b if isdefined(self.inputs.b) else 0)
return runtime
In [1]: a = A(b=2)
In [2]: a.run().outputs
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
...
In [3]: b = OptionalInterface(A(b=2))
In [4]: b.run().outputs
Out[4]:
c = <undefined>
In [5]: b.inputs.a = 5
In [6]: b.run().outputs
Out[6]:
c = 7