def parse_args()

in src/python/pants/option/parser.py [0:0]


  def parse_args(self, parse_args_request):
    """Set values for this parser's options on the namespace object.

    :param Parser.ParseArgsRequest parse_args_request: parameters for parsing this parser's
                                                       arguments.
    :returns: The `parse_args_request.namespace` object that the option values are being registered
              on.
    :raises: :class:`ParseError` if any flags weren't recognized.
    """

    flag_value_map = parse_args_request.flag_value_map
    namespace = parse_args_request.namespace
    get_all_scoped_flag_names = parse_args_request.get_all_scoped_flag_names
    levenshtein_max_distance = parse_args_request.levenshtein_max_distance

    mutex_map = defaultdict(list)
    for args, kwargs in self._unnormalized_option_registrations_iter():
      self._validate(args, kwargs)
      dest = self.parse_dest(*args, **kwargs)

      # Compute the values provided on the command line for this option.  Note that there may be
      # multiple values, for any combination of the following reasons:
      #   - The user used the same flag multiple times.
      #   - The user specified a boolean flag (--foo) and its inverse (--no-foo).
      #   - The option has multiple names, and the user used more than one of them.
      #
      # We also check if the option is deprecated, but we only do so if the option is explicitly
      # specified as a command-line flag, so we don't spam users with deprecated option values
      # specified in config, which isn't something they control.
      implicit_value = kwargs.get('implicit_value')
      if implicit_value is None and kwargs.get('type') == bool:
        implicit_value = True  # Allows --foo to mean --foo=true.

      flag_vals = []

      def add_flag_val(v):
        if v is None:
          if implicit_value is None:
            raise ParseError('Missing value for command line flag {} in {}'.format(
              arg, self._scope_str()))
          else:
            flag_vals.append(implicit_value)
        else:
          flag_vals.append(v)

      for arg in args:
        # If the user specified --no-foo on the cmd line, treat it as if the user specified
        # --foo, but with the inverse value.
        if kwargs.get('type') == bool:
          inverse_arg = self._inverse_arg(arg)
          if inverse_arg in flag_value_map:
            flag_value_map[arg] = [self._invert(v) for v in flag_value_map[inverse_arg]]
            implicit_value = self._invert(implicit_value)
            del flag_value_map[inverse_arg]

        if arg in flag_value_map:
          for v in flag_value_map[arg]:
            add_flag_val(v)
          del flag_value_map[arg]

      # Get the value for this option, falling back to defaults as needed.
      try:
        val = self._compute_value(dest, kwargs, flag_vals)
      except ParseError as e:
        # Reraise a new exception with context on the option being processed at the time of error.
        # Note that other exception types can be raised here that are caught by ParseError (e.g.
        # BooleanConversionError), hence we reference the original exception type as type(e).
        raise type(e)(
          'Error computing value for {} in {} (may also be from PANTS_* environment variables).'
          '\nCaused by:\n{}'.format(', '.join(args), self._scope_str(), traceback.format_exc())
        )

      # If the option is explicitly given, check deprecation and mutual exclusion.
      if val.rank > RankedValue.HARDCODED:
        self._check_deprecated(dest, kwargs)

        mutex_dest = kwargs.get('mutually_exclusive_group')
        if mutex_dest:
          mutex_map[mutex_dest].append(dest)
          dest = mutex_dest
        else:
          mutex_map[dest].append(dest)

        if len(mutex_map[dest]) > 1:
          raise self.MutuallyExclusiveOptionError(
            "Can only provide one of the mutually exclusive options {}".format(mutex_map[dest]))

      setattr(namespace, dest, val)

    # See if there are any unconsumed flags remaining, and if so, raise a ParseError.
    if flag_value_map:
      self._raise_error_for_invalid_flag_names(
        flag_value_map,
        all_scoped_flag_names=list(get_all_scoped_flag_names()),
        levenshtein_max_distance=levenshtein_max_distance)

    return namespace