class_docstr: The real implementation behind external facing ``Tuner``.
  
  The external facing ``Tuner`` multiplexes between local Tuner and remote Tuner
  depending on whether in Ray client mode.
  
  In Ray client mode, external ``Tuner`` wraps ``TunerInternal`` into a remote actor,
  which is guaranteed to be placed on head node.
  
  ``TunerInternal`` can be constructed from fresh, in which case, ``trainable`` needs
  to be provided, together with optional ``param_space``, ``tune_config`` and
  ``run_config``.
  
  It can also be restored from a previous failed run (given ``restore_path``).
  
  Args:
      restore_path: The path from where the Tuner can be restored. If provided, None
          of the rest args are needed.
      resume_config: Resume config to configure which trials to continue.
      trainable: The trainable to be tuned.
      param_space: Search space of the tuning job.
          One thing to note is that both preprocessor and dataset can be tuned here.
      tune_config: Tuning algorithm specific configs.
          Refer to ray.tune.tune_config.TuneConfig for more info.
      run_config: Runtime configuration that is specific to individual trials.
          If passed, this will overwrite the run config passed to the Trainer,
          if applicable. Refer to ray.train.RunConfig for more info.
docstr: Chooses which `RunConfig` to use when multiple can be passed in
  through a Trainer or the Tuner itself.
  
  Args:
      tuner_run_config: The run config passed into the Tuner constructor.
      trainer: The Trainer instance to use with Tune, which may have
          a RunConfig specified by the user.
      param_space: The param space passed to the Tuner.
  
  Raises:
      ValueError: if the `run_config` is specified as a hyperparameter.
docstr_tok: ["Chooses","which","`","RunConfig","`","to","use","when","multiple","can","be","passed","in","through","a","Trainer","or","the","Tuner","itself",".","Args",":","tuner_run_config",":","The","run","config","passed","into","the","Tuner","constructor",".","trainer",":","The","Trainer","instance","to","use","with","Tune",",","which","may","have","a","RunConfig","specified","by","the","user",".","param_space",":","The","param","space","passed","to","the","Tuner",".","Raises",":","ValueError",":","if","the","`","run_config","`","is","specified","as","a","hyperparameter","."]
code: def _choose_run_config(
      self,
      tuner_run_config: Optional[RunConfig],
      trainer: "BaseTrainer",
      param_space: Optional[Dict[str, Any]],
  ) -> RunConfig:
      """Chooses which `RunConfig` to use when multiple can be passed in
      through a Trainer or the Tuner itself.
  
      Args:
          tuner_run_config: The run config passed into the Tuner constructor.
          trainer: The Trainer instance to use with Tune, which may have
              a RunConfig specified by the user.
          param_space: The param space passed to the Tuner.
  
      Raises:
          ValueError: if the `run_config` is specified as a hyperparameter.
      """
      if param_space and "run_config" in param_space:
          raise ValueError(
              "`RunConfig` cannot be tuned as part of the `param_space`! "
              "Move the run config to be a parameter of the `Tuner`: "
              "Tuner(..., run_config=RunConfig(...))"
          )
  
      # Both Tuner RunConfig + Trainer RunConfig --> prefer Tuner RunConfig
      if tuner_run_config and trainer.run_config != RunConfig():
          logger.info(
              "A `RunConfig` was passed to both the `Tuner` and the "
              f"`{trainer.__class__.__name__}`. The run config passed to "
              "the `Tuner` is the one that will be used."
          )
          return tuner_run_config
  
      # No Tuner RunConfig -> pass the Trainer config through
      # This returns either a user-specified config, or the default RunConfig
      # if nothing was provided to both the Trainer or Tuner.
      if not tuner_run_config:
          return trainer.run_config
  
      # Tuner RunConfig + No Trainer RunConfig --> Use the Tuner config
      return tuner_run_config
  
imports: import copy
  import io
  import os
  import math
  import logging
  from pathlib import Path
  from typing import Any, Callable, Dict, List, Optional, Type, Union, TYPE_CHECKING, Tuple
  import pyarrow.fs
  import ray.cloudpickle
  from ray.util import inspect_serializability
  from ray.air._internal.uri_utils import URI
  from ray.air._internal.usage import AirEntrypoint
  from ray.air.config import RunConfig, ScalingConfig
  from ray.train._internal.storage import StorageContext, get_fs_and_path
  from ray.tune import Experiment, TuneError, ExperimentAnalysis
  from ray.tune.execution.experiment_state import _ResumeConfig
  from ray.tune.tune import _Config
  from ray.tune.registry import is_function_trainable
  from ray.tune.result import _get_defaults_results_dir
  from ray.tune.result_grid import ResultGrid
  from ray.tune.trainable import Trainable
  from ray.tune.tune import run
  from ray.tune.tune_config import TuneConfig
  from ray.tune.utils import flatten_dict
label_desc: Use image node_id 12 for calling the TunerInternal obj's underlying member method code with example usage: obj._choose_run_config(tuner_run_config, trainer, param_space) and returns: tuner_run_config, tuner_run_config, trainer