Repository: google/python-fire
File: fire/core.py (Python)

Code before:
        if index + 1 < len(args):
          value = args[index + 1]
          got_argument = True

      keyword = keyword.replace('-', '_')

      # In order for us to consume the argument as a keyword arg, we either:
      # Need to be explicitly expecting the keyword, or we need to be
      # accepting **kwargs.
      if got_argument:
        skip_argument = not contains_equals and not is_bool_syntax
        arg_consumed = True
        if keyword in fn_args or fn_keywords:
          kwargs[keyword] = value
        else:
          remaining_kwargs.append(argument)
          if skip_argument:
            remaining_kwargs.append(args[index + 1])

    # catch boolean shortcut args
    elif re.match('^-[a-z]$', argument):
      keychar = argument[1]
      potential_args = [arg for arg in fn_args if arg[0] == keychar]
      if len(potential_args) == 1:
        arg_consumed = True
        kwargs[potential_args[0]] = 'True'
      elif len(potential_args) > 1:
        raise FireError("The argument '{}' is ambiguous as it could "
                        "refer to any of the following arguments: {}".format(
                            argument, potential_args))

    if not arg_consumed:
      # The argument was not consumed, so it is still a remaining argument.
      remaining_args.append(argument)

  return kwargs, remaining_kwargs, remaining_args


def _ParseValue(value, index, arg, metadata):
  """Parses value, a string, into the appropriate type.

  The function used to parse value is determined by the remaining arguments.

  Args:
    value: The string value to be parsed, typically a command line argument.
    index: The index of the value in the function's argspec.
    arg: The name of the argument the value is being parsed for.
    metadata: Metadata about the function, typically from Fire decorators.
  Returns:
    value, parsed into the appropriate type for calling a function.
  """

Review comment (suggestion):
Instead of always setting to True, let's use the same logic as above for supporting 'contains_equals', checking whether the next arg is a flag, and setting the value accordingly.

I think it's best if we merge the elif that you've added with the if above at 792 since so much of the logic will be shared. I try to clarify this idea in the above comment, but let me know if you want me to clarify further.

Code after:
        # Since there's no next arg or the next arg is a Flag, we consider
        # this flag to be a boolean.
        got_argument = True
        if keyword in fn_args:
          value = 'True'
        elif keyword.startswith('no'):
          keyword = keyword[2:]
          value = 'False'
        else:
          value = 'True'
      else:
        if index + 1 < len(args):
          value = args[index + 1]
          got_argument = True

      keyword = keyword.replace('-', '_')

      # In order for us to consume the argument as a keyword arg, we either:
      # Need to be explicitly expecting the keyword, or we need to be
      # accepting **kwargs.
      if got_argument:
        skip_argument = not contains_equals and not is_bool_syntax
        arg_consumed = True
        if keyword in fn_args or fn_keywords:
          kwargs[keyword] = value
        else:
          remaining_kwargs.append(argument)
          if skip_argument:
            remaining_kwargs.append(args[index + 1])


    if not arg_consumed:
      # The argument was not consumed, so it is still a remaining argument.
      remaining_args.append(argument)

  return kwargs, remaining_kwargs, remaining_args


def _IsFlag(argument):
  """Determines if the argument is a flag argument"""
  return _IsSingleCharFlag(argument) or _IsMultiCharFlag(argument)


def _IsSingleCharFlag(argument):
  """Determines if the argument is a single char flag (e.g. '-a')"""
  return re.match('^-[a-z]$', argument)


def _IsMultiCharFlag(argument):
  """Determines if the argument is a multi char flag (e.g. '--alpha')"""
  return argument.startswith('--')