docs: def read_envvars(name, extension):
      """
      Read environment variables starting with ``NAME_``, where subsequent
      underscores are interpreted as namespaces. Underscores can be retained as
      namespaces by doubling them up, e.g. ``NAME_SPA__CE_KEY`` would be
      accessible in the resulting `.Configuration` as
      ``c.spa_ce.key``, where ``c`` is the `.Configuration` instance.
  
      .. note::
  
          Environment variables are always `str`s, this function makes no effort
          to changes this. All values read from command line variables will be
          `str` instances.
  
      :param name: environment variable prefix to look for (without the ``_``)
      :param extension: *(unused)*
      :return: a `.Configuration` instance, possibly `.NotConfigured`
      """
      prefix = '{}_'.format(name)
      prefix_len = len(prefix)
      envvar_file = '{}_config_file'.format(name)
      # create a new mapping from environment values starting with the prefix (but stripped of that prefix)
      values = {var.lower()[prefix_len:]: value
                for var, value in environ.items()
                # TODO: document ignoring envvar_file
                if var.lower().startswith(prefix) and var.lower() != envvar_file}
      # TODO: envvar values can only be str, how do we configure non-str values?
      if not values:
          return NotConfigured
  
      def dotted(name):
          # replace 'regular' underscores (those between alphanumeric characters) with dots first
          name = re.sub(r'([0-9A-Za-z])_([0-9A-Za-z])', r'\1.\2', name)
          # unescape double underscores back to a single one
          return re.sub(r'__', '_', name)
  
      return Configuration({dotted(name): value for name, value in values.items()})