docs: def _check_for_mismatches(self, known_keys):
          """check for bad options from value sources"""
          for a_value_source in self.values_source_list:
              try:
                  if a_value_source.always_ignore_mismatches:
                      continue
              except AttributeError:
                  # ok, this values source doesn't have the concept
                  # always igoring mismatches, we won't tolerate mismatches
                  pass
              # we want to fetch the keys from the value sources so that we can
              # check for mismatches.  Commandline value sources, are different,
              # we never want to allow unmatched keys from the command line.
              # By detecting if this value source is a command line source, we
              # can employ the command line's own mismatch detection.  The
              # boolean 'allow_mismatches' controls application of the tollerance
              # for mismatches.
              if hasattr(a_value_source, 'command_line_value_source'):
                  allow_mismatches = False
              else:
                  allow_mismatches = True
              # make a set of all the keys from a value source in the form
              # of strings like this: 'x.y.z'
              value_source_mapping = a_value_source.get_values(
                  self,
                  allow_mismatches,
                  self.value_source_object_hook
              )
              value_source_keys_set = set([
                  k for k in
                  DotDict(value_source_mapping).keys_breadth_first()
              ])
              # make a set of the keys that didn't match any of the known
              # keys in the requirements
              unmatched_keys = value_source_keys_set.difference(known_keys)
              # some of the unmatched keys may actually be ok because the were
              # used during acquisition.
              # remove keys of the form 'y.z' if they match a known key of the
              # form 'x.y.z'
              for key in unmatched_keys.copy():
                  key_is_okay = six.moves.reduce(
                      lambda x, y: x or y,
                      (known_key.endswith(key) for known_key in known_keys)
                  )
                  if key_is_okay:
                      unmatched_keys.remove(key)
              # anything left in the unmatched_key set is a badly formed key.
              # issue a warning
              if unmatched_keys:
                  if self.option_definitions.admin.strict.default:
                      # raise hell...
                      if len(unmatched_keys) > 1:
                          raise NotAnOptionError(
                              "%s are not valid Options" % unmatched_keys
                          )
                      elif len(unmatched_keys) == 1:
                          raise NotAnOptionError(
                              "%s is not a valid Option" % unmatched_keys.pop()
                          )
                  else:
                      warnings.warn(
                          'Invalid options: %s' % ', '.join(sorted(unmatched_keys))
                      )