text: import logging
  from logging.config import BaseConfigurator, ConvertingDict, ConvertingList, ConvertingTuple
  from typing import Any, Dict, Tuple, Optional
  
  from configue.converting_mapping import ConvertingMapping
  
  
  class ConfigLoader(BaseConfigurator):
      """A configurator based on logging.config.
  
      Can instantiate classes from a configuration dictionary.
      The instantiation happens when the object is fetched from the configuration.
  
      :ivar config: The parsed configuration.
      """
  
      logger = logging.getLogger(__name__)
  
      def __init__(self, config_dict: Dict) -> None:
          self._config: Optional[ConvertingDict] = None
          BaseConfigurator.__init__(self, config_dict)
          self.config = self.convert(self.config)
  
      @property
      def config(self) -> Any:
          return self._config
  
      @config.setter
      def config(self, config: ConvertingDict) -> None:
          self._config = config
  
      def convert(self, value: Any) -> Any:
          value = BaseConfigurator.convert(self, value)
          if isinstance(value, ConvertingDict):
              value = ConvertingMapping(value)
              if "()" in value:
                  cls_path = value["()"]
                  try:
                      return self.configure_custom(value)
                  except Exception as error:
                      self.logger.error(f"Could not instantiate {cls_path}: {error!r}")
                      raise
          elif isinstance(value, ConvertingList):
              value = list(map(self.convert, value))
          elif isinstance(value, ConvertingTuple):
              value = tuple(map(self.convert, value))
          return value
  
      def cfg_convert(self, value: str) -> Any:
          """Default converter for the cfg:// protocol."""
  
          str_to_parse = value
          match = self.WORD_PATTERN.match(str_to_parse)
          if match is None:
              raise ValueError(f"Unable to convert {value!r}")
          str_to_parse = str_to_parse[match.end():]
          parsed_object = self.config[match.groups()[0]]
          while str_to_parse:
              parsed_object, str_to_parse = self._parse_next_cfg_level(parsed_object, str_to_parse)
          return parsed_object
  
      def _parse_next_cfg_level(self, parsed_object: Any, str_to_parse: str) -> Tuple[Any, str]:
          match = self.DOT_PATTERN.match(str_to_parse)  # parsed_object.property
          if match:
              remaining_str: str = str_to_parse[match.end():]
              if not isinstance(parsed_object, (dict, ConvertingMapping)):
                  return getattr(parsed_object, match.groups()[0]), remaining_str
              return parsed_object[match.groups()[0]], remaining_str
          match = self.INDEX_PATTERN.match(str_to_parse)  # parsed_object[property]
          if not match:
              raise ValueError(f"Unable to convert {str_to_parse!r}")
          remaining_str = str_to_parse[match.end():]
          idx = match.groups()[0]
          if not self.DIGIT_PATTERN.match(idx):  # parsed_object["property"]
              return parsed_object[idx], remaining_str
          return parsed_object[int(idx)], remaining_str  # parsed_object[0]
  