RustPython/RustPython · error · TypeError

'required' is an invalid argument for positionals

Error message

'required' is an invalid argument for positionals

What it means

Positional arguments are inherently required whenever they consume a value: argparse derives required from nargs ('?', '*', '...', SUPPRESS make them non-required) and rejects an explicit required= keyword for positionals with this TypeError in _get_positional_kwargs.

Source

Thrown at Lib/argparse.py:1649

                cont = self
            else:
                cont = title_group_map[group._container.title]
            mutex_group = cont.add_mutually_exclusive_group(
                required=group.required)

            # map the actions to their new mutex group
            for action in group._group_actions:
                group_map[action] = mutex_group

        # add all actions to this container or their group
        for action in container._actions:
            group_map.get(action, self)._add_action(action)

    def _get_positional_kwargs(self, dest, **kwargs):
        # make sure required is not specified
        if 'required' in kwargs:
            msg = "'required' is an invalid argument for positionals"
            raise TypeError(msg)

        # mark positional arguments as required if at least one is
        # always required
        nargs = kwargs.get('nargs')
        if nargs == 0:
            raise ValueError('nargs for positionals must be != 0')
        if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS]:
            kwargs['required'] = True

        # return the keyword arguments with no option strings
        return dict(kwargs, dest=dest, option_strings=[])

    def _get_optional_kwargs(self, *args, **kwargs):
        # determine short and long option strings
        option_strings = []
        long_option_strings = []
        for option_string in args:
            # error on strings that don't start with an appropriate prefix

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Delete required= and let nargs decide; a plain positional is required by default.
  2. To make it optional, use nargs='?' together with default= (e.g. default='out.txt').
  3. To keep explicit required semantics, use an option string: add_argument('-o', '--out', required=True).

Example fix

# before
parser.add_argument('outfile', required=True)
# after
parser.add_argument('outfile', nargs='?', default='out.txt')
Defensive patterns

Strategy: validation

Validate before calling

def add_positional(parser, name, **kwargs):
    if 'required' in kwargs:
        optional = kwargs.pop('required') is False
        if optional:
            kwargs.setdefault('nargs', '?')
    return parser.add_argument(name, **kwargs)

Prevention

When it happens

Trigger: parser.add_argument('outfile', required=True); equally required=False on a positional that consumes a value.

Common situations: Making a positional optional during CLI evolution by adding required=False instead of nargs='?'; copy-paste from an option definition where required= is legal.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/f2bcf6cdd9986f89. Report an issue: GitHub.