paul j3 added the comment:

I'm not quite sure what you mean by 'the enum type to be stored directly'.

With my type function, the string input is converted to an enum object and that 
is stored in the Namespace.  You can't be any more direct than that.

Or are you thinking that `argparse` has some catalog of 'types' that it uses to 
check for value validity and conversion?  There isn't such a collection.  The 
value of the 'type' parameter has to be a callable.  (There is a registry 
mechanism, but that just maps strings on to callables.)

My suggestion does not provide help, but that isn't hard to write that for 
yourself.  A help parameter like:

    help='Enum: {%s}'%','.join([t.name for t in CustomEnumType])

would display:

usage: ipython3 [-h] [-p P]

optional arguments:
  -h, --help  show this help message and exit
  -p P        Enum: {VAL1,VAL2,VAL3}

For really long lists you could write a multiline help and display it with a 
RAW formatter.

I wouldn't use 'choices' with a type function like this.  The type function 
takes care of all the necessary testing and error messaging.  As you write, 
displaying the enum values would just be confusing.


If we define a dictionary wrapper for the enum class, the use of 'choices' 
might not seem so hacky:

     enumDict = {t.name.lower():t for t in CustomEnumType}
     parser.add_argument("-q", default="val1", choices=enumDict)

     parser.print_help()

producing:

usage: ipython3 [-h] [-p P] [-q {val1,val3,val2}]

optional arguments:
  -h, --help           show this help message and exit
  -p P                 Enum: {VAL1,VAL2,VAL3}
  -q {val1,val3,val2}

The keys of a 'choices' dictionary are used automatically in the usage and 
help.  That's nice when there are a few choices, but not so good when there are 
many.  Those problems have been discussed in other bug issues.

This dictionary can be used just like your code to convert the Namespace string 
to an enum object:

    In [57]: parser.parse_args([])
    Out[57]: Namespace(p=<Custom.VAL1: 1>, q='val1')
    In [58]: enumDict[_.q]
    Out[58]: <Custom.VAL1: 1>

And of course 'choices' handles the error listing as well - a plus or minus:

    In [59]: parser.parse_args(['-q','test'])
usage: ipython3 [-h] [-p P] [-q {val1,val3,val2}]
ipython3: error: argument -q: invalid choice: 'test' (choose from 'val1', 
'val3', 'val2')
...

If we are going add anything to streamline the handling of 'enums', it should 
also streamline the handling of any mapping.  The main thing that 'enums' adds 
to Python is a uniqueness constraint - which is an insignificant issue in the 
argparse context.  My custom type function would work just as well with a 
dictionary.  And a dictionary would allow the use of aliases, as well as the 
upper/lower tweaking.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25061>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to