code: def check_confval_types(app: Sphinx | None, config: Config) -> None:
      """Check all values for deviation from the default value's type, since
      that can result in TypeErrors all over the place NB.
      """
      for name, opt in config._options.items():
          default = opt.default
          valid_types = opt.valid_types
          value = getattr(config, name)
  
          if callable(default):
              default = default(config)  # evaluate default value
          if default is None and not valid_types:
              continue  # neither inferable nor explicitly annotated types
  
          if valid_types is Any:  # any type of value is accepted
              continue
  
          if isinstance(valid_types, ENUM):
              if not valid_types.match(value):
                  msg = __(
                      "The config value `{name}` has to be a one of {candidates}, "
                      "but `{current}` is given."
                  )
                  logger.warning(
                      msg.format(
                          name=name,
                          current=value,
                          candidates=valid_types.candidates,
                      ),
                      once=True,
                  )
              continue
  
          type_value = type(value)
          type_default = type(default)
  
          if type_value is type_default:  # attempt to infer the type
              continue
  
          if type_value in valid_types:  # check explicitly listed types
              continue
  
          common_bases = set(
              type_value.__bases__ + (type_value,)
          ) & set(type_default.__bases__)
          common_bases.discard(object)
          if common_bases:
              continue  # at least we share a non-trivial base class
  
          if valid_types:
              msg = __(
                  "The config value `{name}' has type `{current.__name__}'; "
                  "expected {permitted}."
              )
              wrapped_valid_types = sorted(
                  f"`{c.__name__}'" for c in valid_types
              )
              if len(wrapped_valid_types) > 2:
                  permitted = (
                      ", ".join(wrapped_valid_types[:-1])
                      + f", or {wrapped_valid_types[-1]}"
                  )
              else:
                  permitted = " or ".join(wrapped_valid_types)
              logger.warning(
                  msg.format(
                      name=name, current=type_value, permitted=permitted
                  ),
                  once=True,
              )
          else:
              msg = __(
                  "The config value `{name}' has type `{current.__name__}', "
                  "defaults to `{default.__name__}'."
              )
              logger.warning(
                  msg.format(
                      name=name,
                      current=type_value,
                      default=type_default,
                  ),
                  once=True,
              )
  
imports: from __future__ import annotations
  import sys
  import time
  import traceback
  import types
  import warnings
  from os import getenv, path
  from typing import TYPE_CHECKING, Any, Literal, NamedTuple, Union
  from sphinx.deprecation import RemovedInSphinx90Warning
  from sphinx.errors import ConfigError, ExtensionError
  from sphinx.locale import _, __
  from sphinx.util import logging
  from sphinx.util.osutil import fs_encoding
  from sphinx.util.typing import NoneType
label_desc: Use image node_id 9 for calling a global function with example usage: check_confval_types(app, config) without return types