Argparse suggests nonsensical order in help text usage line
Question: This program:

    
    
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('files', metavar='INPUT', nargs='*',
        help='File(s) containing words to include. If none given, stdin will be used.')
    parser.add_argument('-x', '--exclude', nargs='*',
        help='File(s) containing words to exclude.')
    args = parser.parse_args()
    print args.files
    print args.exclude
    

produces this output when run in Python 2.7.9:

    
    
    $ python prog.py --help
    usage: prog.py [-h] [-x [EXCLUDE [EXCLUDE ...]]] [INPUT [INPUT ...]]
    
    positional arguments:
      INPUT                 File(s) containing words to include. If
                            none given, stdin will be used.
    
    optional arguments:
      -h, --help            show this help message and exit
      -x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
                            File(s) containing words to exclude.
    

However, that "help" output instructs the user to use a nonsensical ordering
for the arguments. It is nonsensical because if the `-x` option is used, then
no `INPUT` arguments will be detected.

Argparse ought instead to advise the user to use this ordering:

    
    
    usage: prog.py [-h] [INPUT [INPUT ...]] [-x [EXCLUDE [EXCLUDE ...]]]
    

Two questions:

  1. Is this a bug in `argparse`? (I think it is.)
  2. Regardless of whether it is a bug, how can I fix it so that `$ python prog.py --help` will output the help text I desire (see above), preferably in as [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) a way as possible?


Answer: The simplest way is to add `usage="..."` to `argparse.ArgumentParser()`.

By viewing the source of argparse, I found a way to resort arguments which
might be a little bit dirty:

    
    
    class MyHelpFormatter(argparse.HelpFormatter):
    
        def _format_actions_usage(self, actions, groups):
            actions.sort(key=lambda a: bool(a.option_strings and a.nargs != 0))
            return super(MyHelpFormatter, self)._format_actions_usage(actions, groups)
    
    parser = argparse.ArgumentParser(formatter_class = MyHelpFormatter)
    

