class_docstr: Driver for Resolver.
  
  Constructs an instance of the resolver_class specified by user with configs
  passed in by user and marks the resolved artifacts as the output of the
  Resolver.
code: def pre_execution(
      self,
      input_dict: Dict[str, types.BaseChannel],
      output_dict: Dict[str, types.Channel],
      exec_properties: Dict[str, Any],
      driver_args: data_types.DriverArgs,
      pipeline_info: data_types.PipelineInfo,
      component_info: data_types.ComponentInfo,
  ) -> data_types.ExecutionDecision:
      # Registers contexts and execution
      contexts = self._metadata_handle.register_pipeline_contexts_if_not_exists(
          pipeline_info
      )
      execution = self._metadata_handle.register_execution(
          exec_properties=exec_properties,
          pipeline_info=pipeline_info,
          component_info=component_info,
          contexts=contexts,
      )
      # Gets resolved artifacts.
      resolved = self._build_input_dict(pipeline_info, input_dict)
      maybe_strategy = self._maybe_get_strategy(exec_properties)
      if maybe_strategy:
          resolved = maybe_strategy.resolve_artifacts(
              self._metadata_handle.store, resolved
          )
      if resolved is None:
          # No inputs available. Still driver needs an ExecutionDecision, so use a
          # dummy dict with no artifacts.
          resolved = {key: [] for key in input_dict}
  
      # TODO(b/148828122): This is a temporary workaround for interactive mode.
      for k, c in output_dict.items():
          c.set_artifacts(resolved[k])
      # Updates execution to reflect artifact resolution results and mark
      # as cached.
      self._metadata_handle.update_execution(
          execution=execution,
          component_info=component_info,
          output_artifacts=resolved,
          execution_state=metadata.EXECUTION_STATE_CACHED,
          contexts=contexts,
      )
  
      return data_types.ExecutionDecision(
          input_dict={},
          output_dict=resolved,
          exec_properties=exec_properties,
          execution_id=execution.id,
          use_cached_results=True,
      )
  
imports: import abc
  from typing import Any, Dict, List, Optional, Type, Mapping
  from tfx import types
  from tfx.dsl.components.base import base_driver
  from tfx.dsl.components.base import base_node
  from tfx.dsl.input_resolution import resolver_op
  from tfx.orchestration import data_types
  from tfx.orchestration import metadata
  from tfx.types import channel
  from tfx.types import channel_utils
  from tfx.types import resolved_channel
  from tfx.utils import doc_controls
  from tfx.utils import json_utils
  from tfx.utils import typing_utils
  import ml_metadata
label_desc: Use image node_id 3 for calling the _ResolverDriver obj's underlying member method code with example usage: obj.pre_execution(input_dict, output_dict, exec_properties, driver_args, pipeline_info, component_info) and returns: data_types