Source code for mmodel.node

from mmodel.signature import convert_func, get_node_signature, get_parameters
from mmodel.metadata import nodeformatter
from mmodel.utility import (
    modify_func,
    parse_functype,
    EditMixin,
    ReprMixin,
)
from inspect import signature


[docs] class Node(EditMixin, ReprMixin): """A node class that formats node function and metadata.""" def __init__( self, name, func, inputs=None, output=None, modifiers=None, **kwargs, ): # static self.name = self.__name__ = name self.output = output self._inputs = inputs or [] self._modifiers = modifiers or [] self.func = func self.functype = parse_functype(func) self.doc = func.__doc__ self._base_func = self.convert_func(func, self._inputs) self._node_func = modify_func(self._base_func, self._modifiers) # kwargs can overwrite values like doc, functype, etc. for key, value in kwargs.items(): setattr(self, key, value) @property def node_func(self): """Return node function, the node function cannot be reset.""" return self._node_func @property def __signature__(self): """Node signature for inspection.""" return signature(self.node_func) @property def signature(self): """Return signature.""" return self.__signature__
[docs] def convert_func(self, func, inputs_list): """Convert function to a node function. To replace the positional or positional-or-keyword parameters, the inputs_list needs to be defined. The user can select desired keyword-only parameters after "*" in the input. To replace the keyword-only parameters, a custom function needs to be defined. For functions that already fit the criteria and have no argument list, we still wrap the function. The overhead is minimal. """ base_params = get_parameters(func) node_sig = get_node_signature(base_params, inputs_list) return convert_func(func, node_sig)
@property def inputs(self): """Return a copy of inputs.""" return self._inputs.copy() @property def modifiers(self): """Return a copy of modifiers.""" return self._modifiers.copy()
[docs] def edit(self, **kwargs): """Edit node. A new node object is created. """ # if the the function is updated, the inputs are reset if "func" in kwargs: kwargs["inputs"] = kwargs.get("inputs", None) edit_dict = self.edit_dict edit_dict.update(kwargs) return self.__class__(**edit_dict)
def __call__(self, *args, **kwargs): """Node function callable. The ``node_func`` method is used internally. The ``__call__`` method is used for external calls. """ bound = self.signature.bind(*args, **kwargs) return self.node_func(**bound.arguments) def __str__(self): return nodeformatter(self)