class_docstr: ResolverFunction represents a traceable function of resolver operators.
  
  Resolver function returns some form of channel depending on the function
  definition.
  
  It can return a single channel:
  
      trainer = Trainer(
          examples=latest_created(example_gen.outputs['examples']))
  
  or a dictionary of channels:
  
      k_fold_inputs = k_fold(example_gen.outputs['examples'], splits=5)
      trainer = Trainer(
          examples=k_fold_inputs['train'],
      )
      evaluator = Evaluator(
          examples=k_fold_inputs['eval'],
          model=trainer.outputs['model'],
      )
  
  or a ForEach-loopable channels:
  
    with ForEach(
        tfx.dsl.inputs.sequential_rolling_range(
            example_gens.outputs['examples'], n=3)) as train_window:
      trainer = Trainer(
          examples=train_window['examples'])
docstr: Constructor.
  
  Args:
    f: A python function consists of ResolverOp invocations.
    output_type: Static output type, either a single ArtifactType or a
      dict[str, ArtifactType]. If output_type is not given,
      output_type_inferrer will be used to infer the output type.
    output_type_inferrer: An output type inferrer function, which takes the
      same arguments as the resolver function and returns the output_type. If
      not given, default inferrer (which mirrors the args[0] type) would be
      used.
    loopable_transform: If the resolver function returns
      ARTIFACT_MULTIMAP_LIST, resolver function invocation returns a loopable
      value (the type that can be used with ForEach). This transform function
      is applied to the `ForEach` with clause target value (often called loop
      variable) so that the `as` variables are more easy-to-use. For example,
      one can automatically unwrap the dict key if the dict key is
      internal-only value and would not be exposed to the user side, using
      `loopable_transform = lambda d: d[key]`.
docstr_tok: ["Constructor",".","Args",":","f",":","A","python","function","consists","of","ResolverOp","invocations",".","output_type",":","Static","output","type",",","either","a","single","ArtifactType","or","a","dict","[","str",",","ArtifactType","]",".","If","output_type","is","not","given",",","output_type_inferrer","will","be","used","to","infer","the","output","type",".","output_type_inferrer",":","An","output","type","inferrer","function",",","which","takes","the","same","arguments","as","the","resolver","function","and","returns","the","output_type",".","If","not","given",",","default","inferrer","(","which","mirrors","the","args","[","0","]","type",")","would","be","used",".","loopable_transform",":","If","the","resolver","function","returns","ARTIFACT_MULTIMAP_LIST",",","resolver","function","invocation","returns","a","loopable","value","(","the","type","that","can","be","used","with","ForEach",")",".","This","transform","function","is","applied","to","the","`","ForEach","`","with","clause","target","value","(","often","called","loop","variable",")","so","that","the","`","as","`","variables","are","more","easy-to-use",".","For","example",",","one","can","automatically","unwrap","the","dict","key","if","the","dict","key","is","internal-only","value","and","would","not","be","exposed","to","the","user","side",",","using","`","loopable_transform","=","lambda","d",":","d","[","key","]","`","."]
code: def __init__(
      self,
      f: Callable[..., resolver_op.Node],
      *,
      output_type: Optional[_TypeHint] = None,
      output_type_inferrer: _TypeInferFn = _default_type_inferrer,
      loopable_transform: Optional[_LoopableTransformFn] = None,
  ):
      """Constructor.
  
      Args:
        f: A python function consists of ResolverOp invocations.
        output_type: Static output type, either a single ArtifactType or a
          dict[str, ArtifactType]. If output_type is not given,
          output_type_inferrer will be used to infer the output type.
        output_type_inferrer: An output type inferrer function, which takes the
          same arguments as the resolver function and returns the output_type. If
          not given, default inferrer (which mirrors the args[0] type) would be
          used.
        loopable_transform: If the resolver function returns
          ARTIFACT_MULTIMAP_LIST, resolver function invocation returns a loopable
          value (the type that can be used with ForEach). This transform function
          is applied to the `ForEach` with clause target value (often called loop
          variable) so that the `as` variables are more easy-to-use. For example,
          one can automatically unwrap the dict key if the dict key is
          internal-only value and would not be exposed to the user side, using
          `loopable_transform = lambda d: d[key]`.
      """
      # This instance is a decorated callable so it should reuse the decorated
      # function's system attributes.
      if hasattr(f, "__name__"):
          self.__name__ = f.__name__
      if hasattr(f, "__qualname__"):
          self.__qualname__ = f.__qualname__
      if hasattr(f, "__module__"):
          self.__module__ = f.__module__
      if hasattr(f, "__doc__"):
          self.__doc__ = f.__doc__
      self.__signature__ = inspect.signature(f)
      self.__wrapped__ = f
  
      self._output_type = output_type
      self._output_type_inferrer = output_type_inferrer
      self._loopable_transform = loopable_transform
      self._invocation = None
  
imports: import contextlib
  import inspect
  from typing import Callable, Type, Union, Mapping, Any, Optional, Sequence, cast, overload
  from tfx.dsl.control_flow import for_each_internal
  from tfx.dsl.input_resolution import resolver_op
  from tfx.types import artifact
  from tfx.types import channel
  from tfx.types import resolved_channel
  from tfx.utils import doc_controls
  from tfx.utils import typing_utils
label_desc: Use image node_id 1 to create a new ResolverFunction object  with example: obj = ResolverFunction(f)