code: def _log_sagemaker_config_single_substitution(
      source_value, config_value, config_key_path: str
  ):
      """Informs the SDK user whether a config value was present and automatically substituted
  
      Args:
          source_value: The value that will be used if it exists. Usually, this is user-provided
              input to a Class or to a session.py method, or None if no input was provided.
          config_value: The value fetched from sagemaker_config. If it exists, this is the value that
              will be used if direct_input is None.
          config_key_path: A string denoting the path of keys that point to the config value in the
              sagemaker_config.
  
      Returns:
          None. Logs information to the "sagemaker.config" logger.
      """
      logger = get_sagemaker_config_logger()
  
      if config_value is not None:
          if source_value is None:
              # Sagemaker Config value is going to be used. By default the user should know about
              # this scenario because the behavior they expect could change because of a new config
              # value being injected in.
              # However, it may not be safe to log ARNs to stdout by default. We can include more
              # diagnostic info if the user enabled DEBUG logs though.
              if logger.isEnabledFor(logging.DEBUG):
                  logger.debug(
                      "Applied value\n  config key = %s\n  config value that will be used = %s",
                      config_key_path,
                      config_value,
                  )
              else:
                  logger.info(
                      "Applied value from config key = %s",
                      config_key_path,
                  )
  
          # The cases below here are logged as just debug statements because this info can be useful
          # when debugging the config, but should not affect current behavior with/without the config.
  
          elif (
              source_value is not None and config_value == source_value
          ):
              # Sagemaker Config had a value defined that is NOT going to be used here.
              # Either (1) the config value was already fetched and applied earlier, or
              # (2) the user happened to pass in the same value.
              logger.debug(
                  (
                      "Skipped value\n"
                      "  config key = %s\n"
                      "  config value = %s\n"
                      "  source value that will be used = %s"
                  ),
                  config_key_path,
                  config_value,
                  source_value,
              )
          elif (
              source_value is not None and config_value != source_value
          ):
              # Sagemaker Config had a value defined that is NOT going to be used
              # and the config value has not already been applied earlier (we know because the values
              # are different).
              logger.debug(
                  (
                      "Skipped value\n"
                      "  config key = %s\n"
                      "  config value = %s\n"
                      "  source value that will be used = %s",
                  ),
                  config_key_path,
                  config_value,
                  source_value,
              )
      else:
          # nothing was specified in the config and nothing is being automatically applied
          logger.debug(
              "Skipped value because no value defined\n  config key = %s",
              config_key_path,
          )
  
file_path: sagemaker-python-sdk/src/sagemaker/config/config_utils.py
imports: from __future__ import absolute_import
  from collections import deque
  import logging
  import sys
  from typing import Callable
label_desc: Use image node_id 2 for calling a global function with example usage: _log_sagemaker_config_single_substitution(source_value, config_value, config_key_path) without return types