code: def iter_input_data_keys(
      subtask: Subtask,
      chunk_graph: ChunkGraph,
      chunk_key_to_data_keys: Dict[str, List[str]],
  ) -> Iterator[Tuple[str, bool]]:
      """An iterator yield (input data key, is shuffle)."""
      data_keys = set()
      for chunk in chunk_graph.iter_indep():
          if (
              isinstance(chunk.op, Fetch)
              and chunk.key not in subtask.pure_depend_keys
          ):
              data_keys.add(chunk.key)
              yield chunk.key, False
          elif isinstance(chunk.op, FetchShuffle):
              for key in chunk_key_to_data_keys[chunk.key]:
                  if key not in data_keys:
                      data_keys.add(key)
                      yield key, True
  
imports: from typing import Any, Dict, List, Iterator, Tuple
  from ...core import ChunkGraph
  from ...core.operand import Fetch, FetchShuffle, MapReduceOperand, VirtualOperand
  from .core import Subtask
label_desc: Use image node_id 1 for calling a global function with example usage: iter_input_data_keys(subtask, chunk_graph, chunk_key_to_data_keys) without return types