class_docstr: Configure logging using a dictionary-like object to describe the
  configuration.
class_docstr_tok: ["Configure","logging","using","a","dictionary-like","object","to","describe","the","configuration","."]
docstr: Do the configuration.
docstr_tok: ["Do","the","configuration","."]
code: def configure(self):
      """Do the configuration."""
  
      config = self.config
      if "version" not in config:
          raise ValueError("dictionary doesn't specify a version")
      if config["version"] != 1:
          raise ValueError(
              "Unsupported version: %s" % config["version"]
          )
      incremental = config.pop("incremental", False)
      EMPTY_DICT = {}
      with logging._lock:
          if incremental:
              handlers = config.get("handlers", EMPTY_DICT)
              for name in handlers:
                  if name not in logging._handlers:
                      raise ValueError(
                          "No handler found with " "name %r" % name
                      )
                  else:
                      try:
                          handler = logging._handlers[name]
                          handler_config = handlers[name]
                          level = handler_config.get("level", None)
                          if level:
                              handler.setLevel(
                                  logging._checkLevel(level)
                              )
                      except Exception as e:
                          raise ValueError(
                              "Unable to configure handler " "%r" % name
                          ) from e
              loggers = config.get("loggers", EMPTY_DICT)
              for name in loggers:
                  try:
                      self.configure_logger(name, loggers[name], True)
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure logger " "%r" % name
                      ) from e
              root = config.get("root", None)
              if root:
                  try:
                      self.configure_root(root, True)
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure root " "logger"
                      ) from e
          else:
              disable_existing = config.pop(
                  "disable_existing_loggers", True
              )
  
              _clearExistingHandlers()
  
              # Do formatters first - they don't refer to anything else
              formatters = config.get("formatters", EMPTY_DICT)
              for name in formatters:
                  try:
                      formatters[name] = self.configure_formatter(
                          formatters[name]
                      )
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure " "formatter %r" % name
                      ) from e
              # Next, do filters - they don't refer to anything else, either
              filters = config.get("filters", EMPTY_DICT)
              for name in filters:
                  try:
                      filters[name] = self.configure_filter(
                          filters[name]
                      )
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure " "filter %r" % name
                      ) from e
  
              # Next, do handlers - they refer to formatters and filters
              # As handlers can refer to other handlers, sort the keys
              # to allow a deterministic order of configuration
              handlers = config.get("handlers", EMPTY_DICT)
              deferred = []
              for name in sorted(handlers):
                  try:
                      handler = self.configure_handler(handlers[name])
                      handler.name = name
                      handlers[name] = handler
                  except Exception as e:
                      if " not configured yet" in str(e.__cause__):
                          deferred.append(name)
                      else:
                          raise ValueError(
                              "Unable to configure handler " "%r" % name
                          ) from e
  
              # Now do any that were deferred
              for name in deferred:
                  try:
                      handler = self.configure_handler(handlers[name])
                      handler.name = name
                      handlers[name] = handler
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure handler " "%r" % name
                      ) from e
  
              # Next, do loggers - they refer to handlers and filters
  
              # we don't want to lose the existing loggers,
              # since other threads may have pointers to them.
              # existing is set to contain all existing loggers,
              # and as we go through the new configuration we
              # remove any which are configured. At the end,
              # what's left in existing is the set of loggers
              # which were in the previous configuration but
              # which are not in the new configuration.
              root = logging.root
              existing = list(root.manager.loggerDict.keys())
              # The list needs to be sorted so that we can
              # avoid disabling child loggers of explicitly
              # named loggers. With a sorted list it is easier
              # to find the child loggers.
              existing.sort()
              # We'll keep the list of existing loggers
              # which are children of named loggers here...
              child_loggers = []
              # now set up the new ones...
              loggers = config.get("loggers", EMPTY_DICT)
              for name in loggers:
                  if name in existing:
                      i = existing.index(name) + 1  # look after name
                      prefixed = name + "."
                      pflen = len(prefixed)
                      num_existing = len(existing)
                      while i < num_existing:
                          if existing[i][:pflen] == prefixed:
                              child_loggers.append(existing[i])
                          i += 1
                      existing.remove(name)
                  try:
                      self.configure_logger(name, loggers[name])
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure logger " "%r" % name
                      ) from e
  
              # Disable any old loggers. There's no point deleting
              # them as other threads may continue to hold references
              # and by disabling them, you stop them doing any logging.
              # However, don't disable children of named loggers, as that's
              # probably not what was intended by the user.
              # for log in existing:
              #    logger = root.manager.loggerDict[log]
              #    if log in child_loggers:
              #        logger.level = logging.NOTSET
              #        logger.handlers = []
              #        logger.propagate = True
              #    elif disable_existing:
              #        logger.disabled = True
              _handle_existing_loggers(
                  existing, child_loggers, disable_existing
              )
  
              # And finally, do the root logger
              root = config.get("root", None)
              if root:
                  try:
                      self.configure_root(root)
                  except Exception as e:
                      raise ValueError(
                          "Unable to configure root " "logger"
                      ) from e
  
imports: import errno
  import functools
  import io
  import logging
  import logging.handlers
  import os
  import queue
  import re
  import struct
  import threading
  import traceback
  from socketserver import ThreadingTCPServer, StreamRequestHandler
label_desc: Use image node_id 1 for calling the DictConfigurator obj's underlying member method code with example usage: obj.configure() without return types