[New-bugs-announce] [issue42501] Improve error messages for argparse choices using enum

shangxiao report at bugs.python.org
Sun Nov 29 05:20:31 EST 2020


New submission from shangxiao <shang.xiao.sanders at gmail.com>:

Summary
-------

The argparse module mentions that it will happily accept an enum for the choices argument option [1].  There are currently 2 issues with this:

1. The usage displays non user-friendly values for the enum;
2. The error message for invalid values is not consistent with those provided by iterable-based choices in that it doesn't show the list of available choices. This becomes a problem when you specify the metavar as no choices are displayed at all.


Example of 1
------------

For example using the GameMove example in the argparse documentation:

    class GameMove(Enum):
         ROCK = 'rock'
         PAPER = 'paper'
         SCISSORS = 'scissors'

    parser = argparse.ArgumentParser(prog='game.py')
    parser.add_argument('move', type=GameMove, choices=GameMove)
    parser.print_help()


Gives the usage:

    usage: game.py [-h] {GameMove.ROCK,GameMove.PAPER,GameMove.SCISSORS}

    positional arguments:
      {GameMove.ROCK,GameMove.PAPER,GameMove.SCISSORS}

    optional arguments:
      -h, --help            show this help message and exit


As you can see, the string representations of the valid enum members is used instead of the values.



Example of 2
------------

Below is an example of the error message shown for invalid enum values, with metavar specified:

    parser = argparse.ArgumentParser(prog='game.py')
    parser.add_argument('move', metavar='your-move', type=GameMove, choices=GameMove)
    parser.parse_args(['asdf'])

Gives the following output:

    usage: game.py [-h] your-move
    game.py: error: argument your-move: invalid GameMove value: 'asdf'


This is in contrast with using standard iterable-based choices:

    parser = argparse.ArgumentParser(prog='game.py')
    parser.add_argument('move', metavar='your-move', choices=[x.value for x in GameMove])
    parser.parse_args(['asdf'])

Gives the following output:

    usage: game.py [-h] your-move
    game.py: error: argument your-move: invalid choice: 'asdf' (choose from 'rock', 'paper', 'scissors')


Analysis of 2
--------------

The reason for this behaviour is because argparse attempts to convert to the correct type before checking the choices membership and an invalid enum value results in the first error message.

It would be helpful (& consistent) if the choices are also displayed along with the invalid value message.


Possible Solution
-----------------

I believe that both issues could be solved by using the enum member values in the choices and then checking for choice membership _before_ the value is converted to an enum (ie for enums only).



[1] https://docs.python.org/3/library/argparse.html#choices

----------
components: Library (Lib)
messages: 382051
nosy: shangxiao
priority: normal
severity: normal
status: open
title: Improve error messages for argparse choices using enum
type: behavior
versions: Python 3.10

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue42501>
_______________________________________


More information about the New-bugs-announce mailing list