code: def make_multihop_node_evaluator(
      model_source_nodes: Sequence[BaseOutput],
      semantic_manifest_lookup_with_multihop_links: SemanticManifestLookup,
      desired_linkable_specs: Sequence[LinkableInstanceSpec],
  ) -> NodeEvaluatorForLinkableInstances:  # noqa: D
      """Return a node evaluator using the nodes in multihop_semantic_model_name_to_nodes."""
      node_data_set_resolver: DataflowPlanNodeOutputDataSetResolver = DataflowPlanNodeOutputDataSetResolver(
          column_association_resolver=DunderColumnAssociationResolver(
              semantic_manifest_lookup_with_multihop_links
          ),
          semantic_manifest_lookup=semantic_manifest_lookup_with_multihop_links,
      )
  
      node_processor = PreJoinNodeProcessor(
          semantic_model_lookup=semantic_manifest_lookup_with_multihop_links.semantic_model_lookup,
          node_data_set_resolver=node_data_set_resolver,
      )
  
      nodes_available_for_joins = node_processor.remove_unnecessary_nodes(
          desired_linkable_specs=desired_linkable_specs,
          nodes=model_source_nodes,
          metric_time_dimension_reference=DataSet.metric_time_dimension_reference(),
      )
  
      nodes_available_for_joins = node_processor.add_multi_hop_joins(
          desired_linkable_specs=desired_linkable_specs,
          nodes=nodes_available_for_joins,
          join_type=SqlJoinType.LEFT_OUTER,
      )
  
      return NodeEvaluatorForLinkableInstances(
          semantic_model_lookup=semantic_manifest_lookup_with_multihop_links.semantic_model_lookup,
          nodes_available_for_joins=nodes_available_for_joins,
          node_data_set_resolver=node_data_set_resolver,
      )
  
imports: from __future__ import annotations
  import logging
  from typing import Sequence
  import pytest
  from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity
  from metricflow.dataflow.builder.dataflow_plan_builder import DataflowPlanBuilder
  from metricflow.dataflow.builder.node_data_set import DataflowPlanNodeOutputDataSetResolver
  from metricflow.dataflow.builder.node_evaluator import JoinLinkableInstancesRecipe, LinkableInstanceSatisfiabilityEvaluation, NodeEvaluatorForLinkableInstances
  from metricflow.dataflow.builder.partitions import PartitionTimeDimensionJoinDescription
  from metricflow.dataflow.dataflow_plan import BaseOutput, ValidityWindowJoinDescription
  from metricflow.dataset.dataset import DataSet
  from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup
  from metricflow.plan_conversion.column_resolver import DunderColumnAssociationResolver
  from metricflow.plan_conversion.node_processor import PreJoinNodeProcessor
  from metricflow.specs.specs import DimensionSpec, EntityReference, EntitySpec, LinkableInstanceSpec, LinklessEntitySpec, TimeDimensionSpec
  from metricflow.sql.sql_plan import SqlJoinType
  from metricflow.test.fixtures.model_fixtures import ConsistentIdObjectRepository
label_desc: Use image node_id 2 for calling a global function with example usage: make_multihop_node_evaluator(model_source_nodes, semantic_manifest_lookup_with_multihop_links, desired_linkable_specs) and returns: NodeEvaluatorForLinkableInstances