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: Determines whether the (optionally) re-specified `param_space` is valid.
  
  This method performs very loose validation on the new param_space to
  prevent users from trying to specify new hyperparameters to tune over.
  
  Raises:
      ValueError: if not all keys match the original param_space.
docstr_tok: ["Determines","whether","the","(","optionally",")","re-specified","`","param_space","`","is","valid",".","This","method","performs","very","loose","validation","on","the","new","param_space","to","prevent","users","from","trying","to","specify","new","hyperparameters","to","tune","over",".","Raises",":","ValueError",":","if","not","all","keys","match","the","original","param_space","."]
code: def _validate_param_space_on_restore(
      self,
      new_param_space: Dict[str, Any],
      flattened_param_space_keys: Optional[List[str]],
  ):
      """Determines whether the (optionally) re-specified `param_space` is valid.
  
      This method performs very loose validation on the new param_space to
      prevent users from trying to specify new hyperparameters to tune over.
  
      Raises:
          ValueError: if not all keys match the original param_space.
      """
      if flattened_param_space_keys is None:
          # Backwards compatibility: skip validation
          return
  
      keys = sorted(flatten_dict(new_param_space).keys())
      if keys != flattened_param_space_keys:
          raise ValueError(
              "Invalid `param_space` input to `Tuner.restore()`. To fix this error, "
              "pass in the same `param_space` that was used to initialize the Tuner. "
              "Only re-specify the `param_space` to refresh Ray object references "
              "that no longer exist due to restoring from a new Ray cluster session. "
              "It should not be used to introduce new hyperparameters to tune."
              f"\n\nGot: {keys}\nExpected: {flattened_param_space_keys}"
          )
  
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 8 for calling the TunerInternal obj's underlying member method code with example usage: obj._validate_param_space_on_restore(new_param_space, flattened_param_space_keys) without return types