class_docstr: Base class for executing experiments in parallel.
  
  Parameters:
      root_dir: Path to SCM root.
      dvc_dir: Path to .dvc dir relative to SCM root.
      baseline_rev: Experiment baseline revision.
      wdir: Path to exec working directory relative to SCM root.
      name: Executor (experiment) name.
      result: Completed executor result.
class_docstr_tok: ["Base","class","for","executing","experiments","in","parallel",".","Parameters",":","root_dir",":","Path","to","SCM","root",".","dvc_dir",":","Path","to",".dvc","dir","relative","to","SCM","root",".","baseline_rev",":","Experiment","baseline","revision",".","wdir",":","Path","to","exec","working","directory","relative","to","SCM","root",".","name",":","Executor","(","experiment",")","name",".","result",":","Completed","executor","result","."]
docstr: Run dvc repro and return the result.
  
  Returns tuple of (exp_hash, exp_ref, force) where exp_hash is the
      experiment hash (or None on error), exp_ref is the experiment ref,
      and force is a bool specifying whether or not this experiment
      should force overwrite any existing duplicates.
code: def reproduce(
      cls,
      info: "ExecutorInfo",
      rev: str,
      queue: Optional["Queue"] = None,
      infofile: Optional[str] = None,
      log_errors: bool = True,
      log_level: Optional[int] = None,
      copy_paths: Optional[List[str]] = None,
      message: Optional[str] = None,
      **kwargs,
  ) -> "ExecutorResult":
      """Run dvc repro and return the result.
  
      Returns tuple of (exp_hash, exp_ref, force) where exp_hash is the
          experiment hash (or None on error), exp_ref is the experiment ref,
          and force is a bool specifying whether or not this experiment
          should force overwrite any existing duplicates.
      """
      from dvc.repo.checkout import checkout as dvc_checkout
      from dvc.ui import ui
  
      auto_push = env2bool(DVC_EXP_AUTO_PUSH)
      git_remote = os.getenv(DVC_EXP_GIT_REMOTE, None)
  
      if queue is not None:
          queue.put((rev, os.getpid()))
      if log_errors and log_level is not None:
          cls._set_log_level(log_level)
  
      exp_hash: Optional[str] = None
      exp_ref: Optional["ExpRefInfo"] = None
      repro_force: bool = False
  
      if info.name:
          ui.write(f"Reproducing experiment '{info.name}'")
  
      with cls._repro_dvc(
          info,
          infofile,
          log_errors=log_errors,
          copy_paths=copy_paths,
          message=message,
          **kwargs,
      ) as dvc:
          if auto_push:
              cls._validate_remotes(dvc, git_remote)
  
          args, kwargs = cls._repro_args(dvc)
          if args:
              targets: Optional[Union[list, str]] = args[0]
          else:
              targets = kwargs.get("targets")
  
          repro_force = kwargs.get("force", False)
          logger.trace(
              "Executor repro with force = '%s'", str(repro_force)
          )
  
          repro_dry = kwargs.get("dry")
  
          if not repro_dry:
              dvc_checkout(
                  dvc,
                  targets=targets,
                  with_deps=targets is not None,
                  force=True,
                  allow_missing=True,
                  recursive=kwargs.get("recursive", False),
              )
  
          kwargs["repro_fn"] = cls._repro_and_track
          stages = dvc.reproduce(*args, **kwargs)
          if paths := cls._get_top_level_paths(dvc):
              logger.debug("Staging top-level files: %s", paths)
              dvc.scm_context.add(paths)
  
          exp_hash = cls.hash_exp(stages)
          if not repro_dry:
              ref, exp_ref, repro_force = cls._repro_commit(
                  dvc,
                  info,
                  exp_hash,
                  auto_push,
                  git_remote,
                  repro_force,
                  message=message,
              )
              info.result_hash = exp_hash
              info.result_ref = ref
              info.result_force = repro_force
  
      # ideally we would return stages here like a normal repro() call, but
      # stages is not currently picklable and cannot be returned across
      # multiprocessing calls
      return ExecutorResult(exp_hash, exp_ref, repro_force)
  
imports: import logging
  import os
  import pickle
  import shutil
  from abc import ABC, abstractmethod
  from contextlib import contextmanager
  from dataclasses import asdict, dataclass
  from enum import IntEnum
  from itertools import chain
  from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, List, NamedTuple, Optional, Tuple, Type, TypeVar, Union
  from scmrepo.exceptions import SCMError
  from dvc.env import DVC_EXP_AUTO_PUSH, DVC_EXP_GIT_REMOTE
  from dvc.exceptions import DvcException
  from dvc.log import logger
  from dvc.repo.experiments.exceptions import ExperimentExistsError
  from dvc.repo.experiments.refs import EXEC_BASELINE, EXEC_BRANCH, ExpRefInfo
  from dvc.repo.experiments.utils import to_studio_params
  from dvc.repo.metrics.show import _collect_top_level_metrics
  from dvc.repo.params.show import _collect_top_level_params
  from dvc.stage.serialize import to_lockfile
  from dvc.utils import dict_sha256, env2bool, relpath
  from dvc.utils.fs import remove
  from dvc.utils.studio import env_to_config
label_desc: Use image node_id 18 for calling the BaseExecutor obj's underlying member method code with example usage: obj.reproduce(cls, info, rev, queue, infofile, log_errors, log_level, copy_paths, message) and returns: ExecutorResult