The Node and Pipeline classes have been simplified, but there is now a confusion between ProcessNode and non-process Node: in non-process Node instances, plugs are fields on the Node instance. For ProcessNode instances, plugs fields/values are actually in the underlying process. Node methods get_plug_value() and get_trait() have disappeared, but then we don't have a transparent way of getting / setting fields and values.
For instance in Pipeline.export_parameters(), we have:
# Make a copy of the field
source_field = node.process.field(plug_name)
assumes the node has a process inside, which doesn't work for non-process nodes (switches etc)
then, later in the same function:
# Propagate the parameter value to the new exported one
v = getattr(node, plug_name, undefined)
which, on the contrary, assumes that plug values are on the Node instance itself, which will work for a switch, but not for a process...
So:
either we have to re-introduce Node.get_plug_value() and a replacement for Node.get_trait() (Node.get_field() or Node.get_plug_field() for instance), but the new undefined value behaviour (which throws exceptions) should be catched by explicit try.. except blocks around, because here we cannot use getattr(node, plug_name, undefined).
or we can think of another implementation: let Process inherit Node. Both share many things, and process/non-process nodes thus have an inconsistent shape, that we used to hide by reimplementing access functions to plugs: process nodes were delegating to their underlying self.process, while other nodes were using their own traits. If Node was the base class for Process, this delegation would no longer be needed. As Process instances are most of the time used inside a Pipeline, it would lighten the pipeline objects structure. In non-pipeline implementations, there would be "plugs" on the process which would not be connected, but is it a problem ? Plus, it would remove the need for Pipeline.pipeline_node, and solve (partly only) a number of cyclic references problems between Node and Process when deleting a pipeline that we unsuccessfully tried to solve using weakref and weakproxy cuisine.
The
Node
andPipeline
classes have been simplified, but there is now a confusion betweenProcessNode
and non-processNode
: in non-processNode
instances, plugs are fields on theNode
instance. ForProcessNode
instances, plugs fields/values are actually in the underlying process.Node
methodsget_plug_value()
andget_trait()
have disappeared, but then we don't have a transparent way of getting / setting fields and values. For instance inPipeline.export_parameters()
, we have:assumes the node has a
process
inside, which doesn't work for non-process nodes (switches etc) then, later in the same function:which, on the contrary, assumes that plug values are on the
Node
instance itself, which will work for a switch, but not for a process... So:Node.get_plug_value()
and a replacement forNode.get_trait()
(Node.get_field()
orNode.get_plug_field()
for instance), but the newundefined
value behaviour (which throws exceptions) should be catched by explicittry.. except
blocks around, because here we cannot usegetattr(node, plug_name, undefined)
.Process
inheritNode
. Both share many things, and process/non-process nodes thus have an inconsistent shape, that we used to hide by reimplementing access functions to plugs: process nodes were delegating to their underlyingself.process
, while other nodes were using their own traits. IfNode
was the base class forProcess
, this delegation would no longer be needed. AsProcess
instances are most of the time used inside aPipeline
, it would lighten the pipeline objects structure. In non-pipeline implementations, there would be "plugs" on the process which would not be connected, but is it a problem ? Plus, it would remove the need forPipeline.pipeline_node
, and solve (partly only) a number of cyclic references problems betweenNode
andProcess
when deleting a pipeline that we unsuccessfully tried to solve usingweakref
andweakproxy
cuisine.