docs: def detect_credentials(config_name, extra_environ=None, filenames=None,
                         aws_profile_name=None, default_value=Ellipsis):
      '''
      detect_credentials(config_name) attempts to locate Amazon S3 Bucket credentials from the given
        configuration item config_name.
  
      The following optional arguments are accepted:
        * extra_environ (default: None) may specify a string or a tuple (key_name, secret_name) or a
          list of strings or tuples; strings are treated as an additional environment variable that
          should be checked for credentials while tuples are treated as paired varialbes: if both are
          defined, then they are checked as separate holders of a key/secret pair. Note that a list
          of strings is considered a pair of solo environment varialbes while a tuple of strings is
          considered a single (key_name, secret_name) pair.
        * filenames (default: None) may specify a list of filenames that are checked in order for
          credentials.
        * aws_profile_name (default: None) may specify a profile name that appears in the
          ~/.aws/credentials file that will be checked for aws_access_key_id and aws_secret_access_key
          values. The files ~/.amazon/credentials and ~/.credentials are also checked. Note that this
          may be a list of profiles to check.
        * default_value (default: Ellipsis) may specify a value to return when no credentials are
          found; if this value is None, then it is always returned; otherwise, the value is passed
          through to_credentials() and any errors are allowed to propagate out of
          detect_credentials(). If default_value is Ellipsis then an error is simply raised stating
          that no credentials could be found.
  
      The detect_credentials() function looks at the following locations in the following order,
      assuming that it has been provided with the relevant information:
        * first, if the Neuropythy configuration variable config_name is set via either the npythyrc
          file or the associated environment variable, then it is coerced into credentials;
        * next, if the environment contains both the variables key_name and secret_name (from the 
          optional argument key_secret_environ), then these values are used;
        * next, if the filenames argument is given, then all files it refers to are checked for
          credentials; these files are expanded with both os.expanduser and os.expandvars.
        * finally, if no credentials were detected, an error is raised.
      '''
      # Check the config first:
      if config_name is not None and config[config_name] is not None: return config[config_name]
      # Okay, not found there; check the key/secret environment variables
      if   extra_environ is None: extra_environ = []
      elif pimms.is_str(extra_environ): extra_environ = [extra_environ]
      elif pimms.is_vector(extra_environ):
          if pimms.is_vector(extra_environ, str):
              if len(extra_environ) == 2 and isinstance(extra_environ, _tuple_type):
                  extra_environ = [extra_environ]
      elif not pimms.is_matrix(extra_environ, str):
          raise ValueError('extra_environ must be a string, tuple of strings, or list of these')
      for ee in extra_environ:
          if pimms.is_str(ee):
              if ee in os.environ:
                  try:              return to_credentials(q)
                  except Exception: pass
          elif pimms.is_vector(ee, str) and len(ee) == 2:
              if ee[0] in os.environ and ee[1] in os.environ:
                  (k,s) = [os.environ[q] for q in ee]
                  if len(k) > 0 and len(s) > 0: continue
                  return (k,s)
          else: raise ValueError('cannot interpret extra_environ argument: %s' % ee)
      # Okay, next we check the filenames
      if filenames is None: filenames = []
      elif pimms.is_str(filenames): filenames = [filenames]
      for flnm in filenames:
          flnm = os.expanduser(os.expandvars(flnm))
          if os.path.isfile(flnm):
              try:              return to_credentials(flnm)
              except Exception: pass
      # okay... let's check the AWS credentials file, if it exists
      if pimms.is_str(aws_profile_name): aws_profile_name = [aws_profile_name]
      elif aws_profile_name is None or len(aws_profile_name) == 0: aws_profile_name = None
      elif not pimms.is_vector(aws_profile_name, str):
          raise ValueError('Invalid aws_profile_name value: %s' % aws_profile_name)
      if aws_profile_name is not None:
          try:
              cc = confparse.ConfigParser()
              cc.read([os.expanduser(os.path.join('~', '.aws', 'credentials')),
                       os.expanduser(os.path.join('~', '.amazon', 'credentials')),
                       os.expanduser(os.path.join('~', '.credentials'))])
              for awsprof in aws_profile_names:
                  try:
                      aws_access_key_id     = cc.get(awsprof, 'aws_access_key_id')
                      aws_secret_access_key = cc.get(awsprof, 'aws_secret_access_key')
                      return (aws_access_key_id, aws_secret_access_key)
                  except Exception: pass
          except Exception: pass
      # no match!
      if default_value is None:
          return None
      elif default_value is Ellipsis:
          if config_name is None: raise ValueError('No valid credentials were detected')
          else: raise ValueError('No valid credentials (%s) were detected' % config_name)
      else: return to_credentials(default_value)