[Tutor] argparse csv + choices

Karim karim.liateni at free.fr
Fri Apr 1 18:50:14 CEST 2011


On 03/30/2011 06:05 PM, Robert Kern wrote:
> On 3/30/11 10:32 AM, Neal Becker wrote:
>> I'm trying to combine 'choices' with a comma-seperated list of 
>> options, so I
>> could do e.g.,
>>
>> --cheat=a,b
>>
>>      parser.add_argument ('--cheat', choices=('a','b','c'), 
>> type=lambda x:
>> x.split(','), default=[])
>>
>> test.py --cheat a
>>   error: argument --cheat: invalid choice: ['a'] (choose from 'a', 
>> 'b', 'c')
>>
>> The validation of choice is failing, because parse returns a list, 
>> not an item.
>> Suggestions?
>
> Do the validation in the type function.
>
>
> import argparse
>
> class ChoiceList(object):
>     def __init__(self, choices):
>         self.choices = choices
>
>     def __repr__(self):
>         return '%s(%r)' % (type(self).__name__, self.choices)
>
>     def __call__(self, csv):
>         args = csv.split(',')
>         remainder = sorted(set(args) - set(self.choices))
>         if remainder:
>             raise ValueError("invalid choices: %r (choose from %r)" % 
> (remainder, self.choices))
>         return args
>
>
> parser = argparse.ArgumentParser()
> parser.add_argument('--cheat', type=ChoiceList(['a','b','c']), 
> default=[])
> print parser.parse_args(['--cheat=a,b'])
> parser.parse_args(['--cheat=a,b,d'])
>
Hello,

Great code,

Simply for nicer output could be:

    def __call__(self, csv):
       try:
              args = csv.split(',')
              remainder = sorted(set(args) - set(self.choices))
              if remainder:
                 raise ValueError("invalid choices: %r (choose from %r)" 
% (remainder, self.choices))
              return args
      except ValueError, e:
              raise argparse.ArgumentTypeError(e)

Regards
Karim



More information about the Tutor mailing list