2

Is there a way to produce the equivalent of const (that we can use with nargs='?', see reference question here for an example), but for nargs='*'. Meaning that I would want:

import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument('--option', nargs='*', const=[1, 2, 3])
print(argparser.parse_args())

And then during usage:

my_script.py               #  Namespace(option=None)
my_script.py --option      #  Namespace(option=[1, 2, 3])
my_script.py --option 4 5  #  Namespace(option=[4, 5])

Currently I get ValueError: nargs must be '?' to supply const

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 1
    Without the `const` the second case should produce `option=[]`. You could easily detect and replace that after parsing. – hpaulj Jun 29 '22 at 15:49
  • 1
    The error message you get comes from an explicit test in the `store` Action class "if const is not None and nargs != OPTIONAL:". In `_get_values` 'OPTIONAL' has a special step to handle `const`. Other `nargs` do not. `_get_values` is called before the `Action's` `__call__`. – hpaulj Jun 29 '22 at 15:55

1 Answers1

1

You can use a custom action to achieve this outcome:

import argparse

p = argparse.ArgumentParser()

class customAction(argparse.Action):
    """
    Customized argparse action, will set the
    value in the following way:

        1) If no option_string is supplied: set to None

        2) If option_string is supplied:

            2A) If values are supplied:
                set to list of values

            2B) If no values are supplied:
                set to default value (`self.const`)

    NOTES:
        If `const` is not set, default value (2A) will be None
    """
    def __call__(self, parser, namespace, values, option_string=None):
        if option_string:
            setattr(namespace, self.dest, self.const)
        elif not values:
            setattr(namespace, self.dest, None)
        else:
            setattr(namespace, self.dest, values)


p.add_argument('--option',
    nargs='*',
    action=customAction,
    dest='option',
    type=int,
    const=[1, 2, 3]
)
Yaakov Bressler
  • 9,056
  • 2
  • 45
  • 69