code: def parse_path(experiment_config, config_path):
      """Parse path in config file"""
      expand_path(experiment_config, "searchSpacePath")
      if experiment_config.get("logDir"):
          expand_path(experiment_config, "logDir")
      if experiment_config.get("trial"):
          expand_path(experiment_config["trial"], "codeDir")
          if experiment_config["trial"].get("authFile"):
              expand_path(experiment_config["trial"], "authFile")
          if experiment_config["trial"].get("ps"):
              if experiment_config["trial"]["ps"].get(
                  "privateRegistryAuthPath"
              ):
                  expand_path(
                      experiment_config["trial"]["ps"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("master"):
              if experiment_config["trial"]["master"].get(
                  "privateRegistryAuthPath"
              ):
                  expand_path(
                      experiment_config["trial"]["master"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("worker"):
              if experiment_config["trial"]["worker"].get(
                  "privateRegistryAuthPath"
              ):
                  expand_path(
                      experiment_config["trial"]["worker"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("taskRoles"):
              for index in range(
                  len(experiment_config["trial"]["taskRoles"])
              ):
                  if experiment_config["trial"]["taskRoles"][index].get(
                      "privateRegistryAuthPath"
                  ):
                      expand_path(
                          experiment_config["trial"]["taskRoles"][
                              index
                          ],
                          "privateRegistryAuthPath",
                      )
      if experiment_config.get("tuner"):
          expand_path(experiment_config["tuner"], "codeDir")
      if experiment_config.get("assessor"):
          expand_path(experiment_config["assessor"], "codeDir")
      if experiment_config.get("advisor"):
          expand_path(experiment_config["advisor"], "codeDir")
          if experiment_config["advisor"].get(
              "classArgs"
          ) and experiment_config["advisor"]["classArgs"].get(
              "config_space"
          ):
              expand_path(
                  experiment_config["advisor"]["classArgs"],
                  "config_space",
              )
      if experiment_config.get("machineList"):
          for index in range(len(experiment_config["machineList"])):
              expand_path(
                  experiment_config["machineList"][index], "sshKeyPath"
              )
      if experiment_config["trial"].get("paiConfigPath"):
          expand_path(experiment_config["trial"], "paiConfigPath")
  
      # If users use relative path, convert it to absolute path.
      root_path = os.path.dirname(config_path)
      if experiment_config.get("searchSpacePath"):
          parse_relative_path(
              root_path, experiment_config, "searchSpacePath"
          )
      if experiment_config.get("logDir"):
          parse_relative_path(root_path, experiment_config, "logDir")
      if experiment_config.get("trial"):
          # In AdaptDL mode, 'codeDir' shouldn't be parsed because it points to the path in the container.
          if experiment_config.get("trainingServicePlatform") != "adl":
              parse_relative_path(
                  root_path, experiment_config["trial"], "codeDir"
              )
          if experiment_config["trial"].get("authFile"):
              parse_relative_path(
                  root_path, experiment_config["trial"], "authFile"
              )
          if experiment_config["trial"].get("ps"):
              if experiment_config["trial"]["ps"].get(
                  "privateRegistryAuthPath"
              ):
                  parse_relative_path(
                      root_path,
                      experiment_config["trial"]["ps"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("master"):
              if experiment_config["trial"]["master"].get(
                  "privateRegistryAuthPath"
              ):
                  parse_relative_path(
                      root_path,
                      experiment_config["trial"]["master"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("worker"):
              if experiment_config["trial"]["worker"].get(
                  "privateRegistryAuthPath"
              ):
                  parse_relative_path(
                      root_path,
                      experiment_config["trial"]["worker"],
                      "privateRegistryAuthPath",
                  )
          if experiment_config["trial"].get("taskRoles"):
              for index in range(
                  len(experiment_config["trial"]["taskRoles"])
              ):
                  if experiment_config["trial"]["taskRoles"][index].get(
                      "privateRegistryAuthPath"
                  ):
                      parse_relative_path(
                          root_path,
                          experiment_config["trial"]["taskRoles"][
                              index
                          ],
                          "privateRegistryAuthPath",
                      )
      if experiment_config.get("tuner"):
          parse_relative_path(
              root_path, experiment_config["tuner"], "codeDir"
          )
      if experiment_config.get("assessor"):
          parse_relative_path(
              root_path, experiment_config["assessor"], "codeDir"
          )
      if experiment_config.get("advisor"):
          parse_relative_path(
              root_path, experiment_config["advisor"], "codeDir"
          )
          # for BOHB when delivering a ConfigSpace file directly
          if experiment_config["advisor"].get(
              "classArgs"
          ) and experiment_config["advisor"]["classArgs"].get(
              "config_space"
          ):
              parse_relative_path(
                  root_path,
                  experiment_config["advisor"]["classArgs"],
                  "config_space",
              )
  
      if experiment_config.get("machineList"):
          for index in range(len(experiment_config["machineList"])):
              parse_relative_path(
                  root_path,
                  experiment_config["machineList"][index],
                  "sshKeyPath",
              )
      if experiment_config["trial"].get("paiConfigPath"):
          parse_relative_path(
              root_path, experiment_config["trial"], "paiConfigPath"
          )
  
      # For frameworkcontroller a custom configuration path may be specified
      if experiment_config.get("frameworkcontrollerConfig"):
          if experiment_config["frameworkcontrollerConfig"].get(
              "configPath"
          ):
              parse_relative_path(
                  root_path,
                  experiment_config["frameworkcontrollerConfig"],
                  "configPath",
              )
  
file_path: nni/nni/tools/nnictl/launcher_utils.py
imports: import os
  from schema import SchemaError
  from .config_schema import NNIConfigSchema
  from .common_utils import print_normal
label_desc: Use image node_id 4 for calling a global function with example usage: parse_path(experiment_config, config_path) without return types