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)))
    def get_values(self, config_manager, ignore_mismatches, obj_hook=DotDict):
        """This is the black sheep of the crowd of ValueSource implementations.
        It needs to know ahead of time all of the parameters that it will need,
        but we cannot give it.  We may not know all the parameters because
        not all classes may have been expanded yet.  The two parameters allow
        this ValueSource implementation to know what the parameters  have
        already been defined.  The 'ignore_mismatches' parameter tells the
        implementation if it can or cannot ignore extraneous commandline
        options.  The last time this function is called, it will be required
        to test for illegal commandline options and respond accordingly.

        Unlike many of the Value sources, this method cannot be "memoized".
        The return result depends on an internal state within the parameter
        'config_manager'.  Any memoize decorator for this method would requrire
        capturing that internal state in the memoize cache key.
        """
        short_options_str, long_options_list = self.getopt_create_opts(
            config_manager.option_definitions)
        try:
            if ignore_mismatches:
                fn = ValueSource.getopt_with_ignore
            else:
                fn = getopt.gnu_getopt
            # here getopt looks through the command line arguments and
            # consumes the defined switches.  The things that are not
            # consumed are then offered as the 'args' variable of the
            # parent configuration_manager
            getopt_options, config_manager.args = fn(self.argv_source,
                                                     short_options_str,
                                                     long_options_list)
        except getopt.GetoptError as x:
            raise NotAnOptionError(str(x))
        command_line_values = obj_hook()
        for opt_name, opt_val in getopt_options:
            if opt_name.startswith('--'):
                name = opt_name[2:]
            else:
                name = self.find_name_with_short_form(
                    opt_name[1:], config_manager.option_definitions, '')
                if not name:
                    raise NotAnOptionError(
                        '%s is not a valid short form option' % opt_name[1:])
            option_ = config_manager._get_option(name)
            if option_.from_string_converter == boolean_converter:
                command_line_values[name] = not option_.default
            else:
                command_line_values[name] = opt_val
        for name, value in zip(
                self._get_arguments(config_manager.option_definitions,
                                    command_line_values), config_manager.args):
            command_line_values[name] = value
        return command_line_values
Exemplo n.º 3
0
    def get_values(self, config_manager, ignore_mismatches, obj_hook=DotDict):
        """This is the black sheep of the crowd of ValueSource implementations.
        It needs to know ahead of time all of the parameters that it will need,
        but we cannot give it.  We may not know all the parameters because
        not all classes may have been expanded yet.  The two parameters allow
        this ValueSource implementation to know what the parameters  have
        already been defined.  The 'ignore_mismatches' parameter tells the
        implementation if it can or cannot ignore extraneous commandline
        options.  The last time this function is called, it will be required
        to test for illegal commandline options and respond accordingly.

        Unlike many of the Value sources, this method cannot be "memoized".
        The return result depends on an internal state within the parameter
        'config_manager'.  Any memoize decorator for this method would requrire
        capturing that internal state in the memoize cache key.
        """
        short_options_str, long_options_list = self.getopt_create_opts(
            config_manager.option_definitions
        )
        try:
            if ignore_mismatches:
                fn = ValueSource.getopt_with_ignore
            else:
                fn = getopt.gnu_getopt
            # here getopt looks through the command line arguments and
            # consumes the defined switches.  The things that are not
            # consumed are then offered as the 'args' variable of the
            # parent configuration_manager
            getopt_options, config_manager.args = fn(self.argv_source,
                                                     short_options_str,
                                                     long_options_list)
        except getopt.GetoptError, x:
            raise NotAnOptionError(str(x))
 def _get_option(self, name):
     try:
         return self.option_definitions[name]
     except KeyError:
         raise NotAnOptionError('%s is not a known option name' % name)
Exemplo n.º 5
0
class ValueSource(object):
    """The ValueSource implementation for the getopt module.  This class will
    interpret an argv list of commandline arguments using getopt."""
    #--------------------------------------------------------------------------
    def __init__(self, source, the_config_manager=None):
        if source is getopt:
            self.argv_source = the_config_manager.argv_source
        elif isinstance(source, collections.Sequence):
            self.argv_source = source
        else:
            raise CantHandleTypeException()

    # frequently, command line data sources must be treated differently.  For
    # example, even when the overall option for configman is to allow
    # non-strict option matching, the command line should not arbitrarily
    # accept bad command line switches.  The existance of this key will make
    # sure that a bad command line switch will result in an error without
    # regard to the overall --admin.strict setting.
    command_line_value_source = True

    #--------------------------------------------------------------------------
    def get_values(self, config_manager, ignore_mismatches, obj_hook=DotDict):
        """This is the black sheep of the crowd of ValueSource implementations.
        It needs to know ahead of time all of the parameters that it will need,
        but we cannot give it.  We may not know all the parameters because
        not all classes may have been expanded yet.  The two parameters allow
        this ValueSource implementation to know what the parameters  have
        already been defined.  The 'ignore_mismatches' parameter tells the
        implementation if it can or cannot ignore extraneous commandline
        options.  The last time this function is called, it will be required
        to test for illegal commandline options and respond accordingly.

        Unlike many of the Value sources, this method cannot be "memoized".
        The return result depends on an internal state within the parameter
        'config_manager'.  Any memoize decorator for this method would requrire
        capturing that internal state in the memoize cache key.
        """
        short_options_str, long_options_list = self.getopt_create_opts(
            config_manager.option_definitions
        )
        try:
            if ignore_mismatches:
                fn = ValueSource.getopt_with_ignore
            else:
                fn = getopt.gnu_getopt
            # here getopt looks through the command line arguments and
            # consumes the defined switches.  The things that are not
            # consumed are then offered as the 'args' variable of the
            # parent configuration_manager
            getopt_options, config_manager.args = fn(self.argv_source,
                                                     short_options_str,
                                                     long_options_list)
        except getopt.GetoptError, x:
            raise NotAnOptionError(str(x))
        command_line_values = obj_hook()
        for opt_name, opt_val in getopt_options:
            if opt_name.startswith('--'):
                name = opt_name[2:]
            else:
                name = self.find_name_with_short_form(
                    opt_name[1:],
                    config_manager.option_definitions,
                    ''
                )
                if not name:
                    raise NotAnOptionError(
                        '%s is not a valid short form option' % opt_name[1:]
                    )
            option_ = config_manager._get_option(name)
            if option_.from_string_converter == boolean_converter:
                command_line_values[name] = not option_.default
            else:
                command_line_values[name] = opt_val
        for name, value in zip(
            self._get_arguments(
                config_manager.option_definitions,
                command_line_values
            ),
            config_manager.args
        ):
            command_line_values[name] = value
        return command_line_values