code: def restore(
      self, stage, run_cache=True, pull=False, dry=False
  ):  # noqa: C901
      from .serialize import to_single_stage_lockfile
  
      if not _can_hash(stage):
          raise RunCacheNotFoundError(stage)
  
      if (
          not stage.changed_stage()
          and stage.deps_cached()
          and all(bool(out.hash_info) for out in stage.outs)
      ):
          cache = to_single_stage_lockfile(stage)
      else:
          if not run_cache:  # backward compatibility
              raise RunCacheNotFoundError(stage)
          if not dry:
              stage.save_deps()
          cache = self._load(stage)
          if not cache:
              raise RunCacheNotFoundError(stage)
  
      cached_stage = self._create_stage(cache, wdir=stage.wdir)
  
      if pull and not dry:
          try:
              for objs in cached_stage.get_used_objs().values():
                  self.repo.cloud.pull(objs)
          except CollectCacheError as exc:
              raise RunCacheNotFoundError(stage) from exc
  
      if not cached_stage.outs_cached():
          raise RunCacheNotFoundError(stage)
  
      logger.info(
          "Stage '%s' is cached - skipping run, checking out outputs",
          stage.addressing,
      )
      if not dry:
          cached_stage.checkout()
  
imports: import os
  from contextlib import contextmanager
  from typing import TYPE_CHECKING, List, Optional, Tuple
  from funcy import first
  from dvc import fs
  from dvc.config import RemoteConfigError
  from dvc.exceptions import CollectCacheError, DvcException
  from dvc.log import logger
  from dvc.utils import dict_sha256, relpath
label_desc: Use image node_id 10 for calling the StageCache obj's underlying member method code with example usage: obj.restore(stage, run_cache, pull, dry) without return types