def readNodeClassFactory(dataPacketType):
    dataType = dataPacketType.__name__[len("DataPacket"):]
    NewClassType = type('DagNode'+dataType+'Read', (DagNode,), {})

    # Create the new DagNode's init function
    def init(self, name=""):
        DagNode.__init__(self, name)
    NewClassType.__init__ = init
    
    # Create the new DagNode's defineInputs function
    def _defineInputs(self):
        return list()
    NewClassType._defineInputs = _defineInputs
    
    # Create the new DagNode's defineOutputs function
    def _defineOutputs(self):
        return [DagNodeOutput(dataPacketType.__name__[len('DataPacket'):], dataPacketType)]
    NewClassType._defineOutputs = _defineOutputs
    
    # Create the new DagNode's defineAttributes function
    def _defineAttributes(self):
        return list()
    NewClassType._defineAttributes = _defineAttributes
    
    # Create the executeList function
    def executeList(self, dataPacketDict, splitOperations=False):
        pass
    NewClassType.executeList = executeList

    # Create the validate function
    def validate(self):
        # Calling sceneGraphHandle without a specialized type works because we are just
        # checking the presence of data; not whether its type matches or anything else fancy.
        for output in self.outputs():
            if not self.sceneGraphHandle()[0].dataPresent(): # TODO: sceneGraphHandle should not return an array (see other yadda yaddas)
                raise RuntimeError("Data is not present for %s output." % output.name)
        return True
    NewClassType.validate = validate

    return NewClassType


######################### GENERATE READ DAG NODES #############################
Create a new DagNode...Read node from a given dataPacket type.
dataset/ETHPy150Open andrew-gardner/dependsworkflow/depends/depends_node.py/readNodeClassFactory