This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author paul.j3
Recipients barry, desbma, paul.j3
Date 2015-09-13.20:03:16
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1442174596.82.0.95873424982.issue25061@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2015-09-13 20:03:16paul.j3setrecipients: + paul.j3, barry, desbma
2015-09-13 20:03:16paul.j3setmessageid: <1442174596.82.0.95873424982.issue25061@psf.upfronthosting.co.za>
2015-09-13 20:03:16paul.j3linkissue25061 messages
2015-09-13 20:03:16paul.j3create