def _set_unknown_flag(self, name, value): """Returns value if setting flag |name| to |value| returned True. Args: name: str, name of the flag to set. value: Value to set. Returns: Flag value on successful call. Raises: UnrecognizedFlagError IllegalFlagValueError """ setter = self.__dict__['__set_unknown'] if setter: try: setter(name, value) return value except (TypeError, ValueError): # Flag value is not valid. raise _exceptions.IllegalFlagValueError( '"{1}" is not valid for --{0}' .format(name, value)) except NameError: # Flag name is not valid. pass raise _exceptions.UnrecognizedFlagError(name, value)
def parse(self, argument): """Parses string and sets flag value. Args: argument: str or the correct flag value type, argument to be parsed. """ if self.present and not self.allow_overwrite: raise _exceptions.IllegalFlagValueError( 'flag --%s=%s: already defined as %s' % (self.name, argument, self.value)) self.value = self._parse(argument) self.present += 1
def _parse(self, argument): """Internal parse function. It returns the parsed value, and does not modify class states. Args: argument: str or the correct flag value type, argument to be parsed. Returns: The parsed value. """ try: return self.parser.parse(argument) except (TypeError, ValueError) as e: # Recast as IllegalFlagValueError. raise _exceptions.IllegalFlagValueError( 'flag --%s=%s: %s' % (self.name, argument, e))
def __setitem__(self, name, flag): """Registers a new flag variable.""" fl = self._flags() if not isinstance(flag, _flag.Flag): raise _exceptions.IllegalFlagValueError(flag) if str is bytes and isinstance(name, unicode): # When using Python 2 with unicode_literals, allow it but encode it # into the bytes type we require. name = name.encode('utf-8') if not isinstance(name, type('')): raise _exceptions.Error('Flag name must be a string') if not name: raise _exceptions.Error('Flag name cannot be empty') if ' ' in name: raise _exceptions.Error('Flag name cannot contain a space') self._check_method_name_conflicts(name, flag) if name in fl and not flag.allow_override and not fl[ name].allow_override: module, module_name = _helpers.get_calling_module_object_and_name() if (self.find_module_defining_flag(name) == module_name and id(module) != self.find_module_id_defining_flag(name)): # If the flag has already been defined by a module with the same name, # but a different ID, we can stop here because it indicates that the # module is simply being imported a subsequent time. return raise _exceptions.DuplicateFlagError.from_flag(name, self) short_name = flag.short_name # If a new flag overrides an old one, we need to cleanup the old flag's # modules if it's not registered. flags_to_cleanup = set() if short_name is not None: if (short_name in fl and not flag.allow_override and not fl[short_name].allow_override): raise _exceptions.DuplicateFlagError.from_flag( short_name, self) if short_name in fl and fl[short_name] != flag: flags_to_cleanup.add(fl[short_name]) fl[short_name] = flag if (name not in fl # new flag or fl[name].using_default_value or not flag.using_default_value): if name in fl and fl[name] != flag: flags_to_cleanup.add(fl[name]) fl[name] = flag for f in flags_to_cleanup: self._cleanup_unregistered_flag_from_module_dicts(f)
def _assert_validators(self, validators): """Asserts if all validators in the list are satisfied. It asserts validators in the order they were created. Args: validators: Iterable(validators.Validator), validators to be verified. Raises: AttributeError: Raised if validators work with a non-existing flag. IllegalFlagValueError: Raised if validation fails for at least one validator. """ for validator in sorted( validators, key=lambda validator: validator.insertion_index): try: validator.verify(self) except _exceptions.ValidationError as e: message = validator.print_flags_with_values(self) raise _exceptions.IllegalFlagValueError('%s: %s' % (message, str(e)))
def read_flags_from_files(self, argv, force_gnu=True): """Processes command line args, but also allow args to be read from file. Args: argv: [str], a list of strings, usually sys.argv[1:], which may contain one or more flagfile directives of the form --flagfile="./filename". Note that the name of the program (sys.argv[0]) should be omitted. force_gnu: bool, if False, --flagfile parsing obeys normal flag semantics. If True, --flagfile parsing instead follows gnu_getopt semantics. *** WARNING *** force_gnu=False may become the future default! Returns: A new list which has the original list combined with what we read from any flagfile(s). Raises: IllegalFlagValueError: Raised when --flagfile is provided with no argument. This function is called by FLAGS(argv). It scans the input list for a flag that looks like: --flagfile=<somefile>. Then it opens <somefile>, reads all valid key and value pairs and inserts them into the input list in exactly the place where the --flagfile arg is found. Note that your application's flags are still defined the usual way using absl.flags DEFINE_flag() type functions. Notes (assuming we're getting a commandline of some sort as our input): --> For duplicate flags, the last one we hit should "win". --> Since flags that appear later win, a flagfile's settings can be "weak" if the --flagfile comes at the beginning of the argument sequence, and it can be "strong" if the --flagfile comes at the end. --> A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile. It will be expanded in exactly the spot where it is found. --> In a flagfile, a line beginning with # or // is a comment. --> Entirely blank lines _should_ be ignored. """ rest_of_args = argv new_argv = [] while rest_of_args: current_arg = rest_of_args[0] rest_of_args = rest_of_args[1:] if self._is_flag_file_directive(current_arg): # This handles the case of -(-)flagfile foo. In this case the # next arg really is part of this one. if current_arg == '--flagfile' or current_arg == '-flagfile': if not rest_of_args: raise _exceptions.IllegalFlagValueError( '--flagfile with no argument') flag_filename = os.path.expanduser(rest_of_args[0]) rest_of_args = rest_of_args[1:] else: # This handles the case of (-)-flagfile=foo. flag_filename = self._extract_filename(current_arg) new_argv.extend(self._get_flag_file_lines(flag_filename)) else: new_argv.append(current_arg) # Stop parsing after '--', like getopt and gnu_getopt. if current_arg == '--': break # Stop parsing after a non-flag, like getopt. if not current_arg.startswith('-'): if not force_gnu and not self.__dict__['__use_gnu_getopt']: break else: if ('=' not in current_arg and rest_of_args and not rest_of_args[0].startswith('-')): # If this is an occurrence of a legitimate --x y, skip the value # so that it won't be mistaken for a standalone arg. fl = self._flags() name = current_arg.lstrip('-') if name in fl and not fl[name].boolean: current_arg = rest_of_args[0] rest_of_args = rest_of_args[1:] new_argv.append(current_arg) if rest_of_args: new_argv.extend(rest_of_args) return new_argv