You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Improve error messages for argparse choices using enum #86667
The argparse module mentions that it will happily accept an enum for the choices argument option [1]. There are currently 2 issues with this:
The usage displays non user-friendly values for the enum;
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:
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:
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).
Oh apologies, I had "open" selected when I searched for prior issues.
Upon reading that issue I agree with Mr Hettinger's points about enum values not being a concern of the parser.
The solution for my needs was simple enough: I made my own action which simply set choices based on member values (I'm using user-friendly strings) and converted to the correct type upon being called [1].
Instead of removing any mention of enums from the docs - would a small example showing how to deal with them be worthwhile?
choices is fine for a few strings, but quickly becomes awkward with other types and large numbers. The testing isn't an issue, since it just does a simple in/contains test. But display, whether in usage, help or error, is problematic if you try anything too fancy. metavar gets around some of those issues, but doesn't change the error messages.
Custom type or action is the best alternative.
I'm in favor omitting the enums mention in the docs, since it seems to be more confusing than helpful.
Activity
shangxiao commentedon Nov 29, 2020
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:
Example of 1
------------
For example using the GameMove example in the argparse documentation:
Gives the usage:
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:
Gives the following output:
This is in contrast with using standard iterable-based choices:
Gives the following output:
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
rhettinger commentedon Nov 29, 2020
I'm inclined to state in the docs that choices is designed to work with collections of strings and that there is no special support for enums.
Paul, what do you think?
tirkarthi commentedon Nov 29, 2020
https://bugs.python.org/issue25061 also had some discussion over error message display for enums
shangxiao commentedon Nov 29, 2020
Oh apologies, I had "open" selected when I searched for prior issues.
Upon reading that issue I agree with Mr Hettinger's points about enum values not being a concern of the parser.
The solution for my needs was simple enough: I made my own action which simply set choices based on member values (I'm using user-friendly strings) and converted to the correct type upon being called [1].
Instead of removing any mention of enums from the docs - would a small example showing how to deal with them be worthwhile?
[1]
def enum_action_factory(enum_class):
paulj3 commentedon Nov 29, 2020
choices is fine for a few strings, but quickly becomes awkward with other types and large numbers. The testing isn't an issue, since it just does a simple
in/containstest. But display, whether in usage, help or error, is problematic if you try anything too fancy. metavar gets around some of those issues, but doesn't change the error messages.Custom type or action is the best alternative.
I'm in favor omitting the enums mention in the docs, since it seems to be more confusing than helpful.
rhettinger commentedon Nov 29, 2020
How does PR 23563 look to you all?
rhettinger commentedon Nov 30, 2020
New changeset 7f82f22 by Raymond Hettinger in branch 'master':
bpo-42501: Revise the usage note for Enums with the choices (GH-23563)
7f82f22
rhettinger commentedon Nov 30, 2020
New changeset aab9390 by Miss Islington (bot) in branch '3.9':
bpo-42501: Revise the usage note for Enums with the choices (GH-23563) (GH-23573)
aab9390