Add "maybe you meant" in argparse `choices` argument

Argpars is definitely aimed at the end user, and it would be nicer if it assumes what you mean.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--style", "-s", choices=["Bold", "Italic", "Normal", "Nope"])
args = parser.parse_args(["-s", "None"])
usage: temp_iiec_codefile.py [-h]
                             [--style {Bold,Italic,Normal,Nope}]
temp_iiec_codefile.py: error: argument --style/-s: invalid choice: 'None', maybe you meant 'Nope'? (choose from 'Bold', 'Italic', 'Normal', 'Nope')

Now he doesn’t do that.

1 Like

argparse already has that; that’s why the error message specifically mentions “Nope” as it is closest to “None”.

The suggestion is to skip the error and just assume the user meant the closest legal option. However, that’s dangerous, because the suggestion is sometimes wrong. I regularly encounter “did you mean” suggestions that aren’t what I meant.

5 Likes

DWIM or Do What I Mean

2 Likes

Does it? I can’t reproduce that output; perhaps it was manually edited to show the suggested behavior?

That said, I’m not sure it’s worth the extra processing and output to give a suggestion here. All options are already shown, and the best suggestion we could give would in the end just be a guess (which is a temptation we should refuse :wink: ).

I think it is fine to guess if it is just for displaying better error message. Guessing becomes a problem if we decide to guess what the user meant, and continue running without any error assuming the nearest match was what the user wanted.

Part of the error message improvements in 3.10 are about suggesting the nearest match to what the user typed in case of AttributeError or NameError. What’s New In Python 3.10 — Python 3.10.8 documentation

1 Like

I think there’s been some linguistic confusion here, but my reading of the OP’s request was simply to display the closest legal option, not to assume it.

2 Likes

That seems overly pessimistic. difflib.get_close_matches exists in the stdlib to provide similarity score comparisons for strings. We use it in Bokeh to offer suggestions for attribute errors and more than a few people over the years have expressed pleasant surprise at this feature:

In [4]: r.bounda = 10

AttributeError: unexpected attribute 'bounda' to Range1d, similar attributes are: bounds

If there is no close matches, then we just list them all (but sometimes there are alot, which is why this is nice).

2 Likes

friendly/friendly-traceback also does this (but with its own custom function rather than using Python’s
difflib module, which is something that seems to be appreciated by its users. I think that such an addition would be welcomed by many argparse end-users.

2 Likes

Yes, I think I misread. Sorry for that!

1 Like

Yes exactly.

The example may not be perfect, and the error output may be different.

1 Like