python / cpython

The Python programming language
https://www.python.org
Other
62.89k stars 30.13k forks source link

Documentation of `argparse.add_argument`s `append` should mention `dest` #92928

Open jugmac00 opened 2 years ago

jugmac00 commented 2 years ago

The current documentation of append shows this example:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])

Working then with foo, which indeed is a collection of foos felt wrong, but I did not know what to do about it.

A colleague pointed out that there is the dest keyword, so you can rewrite this as...

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append', dest='foos')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foos=['1', '2'])

I think it would be a good idea to keep the current version of the example, but to reference the dest keyword to get a proper naming for the collection of values.

If this sounds about right, I'd like to create a pull request.

erlend-aasland commented 2 years ago

The very first argparse example uses the dest keyword. There is more than a handful of other examples that use the dest keyword.

erlend-aasland commented 2 years ago

FTR, this is the very first example shown in the argparse docs:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))
jugmac00 commented 2 years ago

Thanks for getting back to me.

The very first argparse example uses the dest keyword. There is more than a handful of other examples that use the dest keyword.

The very first example does not even explain the dest keyword.

The introductory paragraph of https://docs.python.org/3/library/argparse.html says: "This page contains the API reference information."

In my print preview, the API reference is 32 pages.

"There are is more than a handful of other examples".

Usually, an API reference is not meant to be read from beginning to the end.

So no, I did not read the other examples, I went straight to the documentation about append, as I needed that feature, and I would have liked some reference to the dest keyword, as I think these two go perfectly with each other.

erlend-aasland commented 2 years ago

Would you like to propose a change in a PR?

jugmac00 commented 2 years ago

Would you like to propose a change in a PR?

Indeed, I'd like to create a pull request. Before doing that, I just wanted to get some feedback whether it would be accepted, but your question implies this :-) Let me see whether I can make it today or on the weekend.

rhettinger commented 2 years ago

In my print preview, the API reference is 32 pages.

I would like for this situation to not be made worse by adding more volume. The reference needs to be smaller and has already gone egregiously far with too many mostly repetitive examples.

If you want to submit a PR, look at modifying the argparse howto guide. It is intended to be a tutorial. IN contrast, the main reference needs to be more compartmentalized.

jugmac00 commented 2 years ago

The reference from append to dest would make so much sense.

Screenshot from 2022-05-19 21-43-24

What if I could shorten it to one additional line? :-)

The tutorial neither refers to dest nor to append, so it would need a whole new section.

I still would prefer the change in the API reference.

In my print preview, the API reference is 32 pages.

I would like for this situation to not be made worse by adding more volume.

I do not think 32 or even more pages are bad - it is an API reference, you go the the thing you want to look up, it is just nothing I would want to read from top to bottom.

facundobatista commented 2 years ago

+1 to a small comment about dest in the append section

slateny commented 2 years ago

If someone uses append, wouldn't they first go to the add_argument section and notice the dest arg? I would concur with the change if dest was used solely for append, but it looks like it can be used with various other arguments, so to me it doesn't seem too appropriate to add this note just for append.

A quick search on the argparse howto page still shows no sections on using dest, but I would agree that inserting the short sentence/section there seems a bit better.

jugmac00 commented 2 years ago

Hey @slateny,

I cannot speak for others, I can only speak for myself.

When I wanted to use append, I directly went to the API documentation for append, and I did not look up add_argument.

I can only repeat that while dest might be used in other combinations, append and dest are natural fits, as at least I collect single items with append and then want to work with a more appropriate name in plural form.

Unlike the mentioned suggestions, I do not think that the tutorial is the best place for this information.

If the Python documentation picks up the Diátaxis framework, this information might fit in a how-to, though.

Until then, as a long-term Python user, I would not visit the tutorial page, work through dozens of pages to maybe learn something new, but I usually go straight to the API documentation. Unlike other opinions expressed here, I do not think an API documentation needs to be "smaller", imho it needs to be comprehensive, and imho the difference between a complete and a really good API documentation are those little gems of information like the mentioned fit between append and dest.

hpaulj commented 1 year ago

I think the use of dest is sufficiently well documented under its own heading. The last example is

 dest allows a custom attribute name to be provided:

 >>>parser = argparse.ArgumentParser()
 parser.add_argument('--foo', dest='bar')
 parser.parse_args('--foo XXX'.split())
 Namespace(bar='XXX')

Suggesting 'foos' for append is just a matter of English semantics. You could also get multiple "foo" in a list of "foo" if nargs="+".

The dest can be just as useful with other Action classes. You might want use to a long option string like '--url-to-load' (and any abbreviation), but just use a short args.url. The custom dest is also useful when the long option string contains special characters (which can't be used as an attribute name).

Closely related to the dest is the metavar, which can override the help display.

Have you considered what the help looks like with the dest='foos'?

   parser.print_help()
   usage: ipykernel_launcher.py [-h] [--foo FOOS]
   optional arguments:
          -h, --help  show this help message and exit
          --foo FOOS

One Action class where dest has a special role is add_subparsers. If you want to see what command was given, you have to specify a dest. The default dest for this Action class is None.

When debugging a parser, it's often a good idea to include a print(args) statement. That way you see what dest the parser is using, and won't get errors because you made some wrong guesses.