1

I created the next "parent" parser:

parent_parser = argparse.ArgumentParser(add_help=False)
base_group = parser.add_argument_group(title = "global arguments")                                                     
base_group.add_argument("-l", "--log-file", metavar="FILE", help="set log file (default no log)")                      
base_group.add_argument("-c", "--clear-log", action="store_true", default=False, help="clear log file before logging") 

mutex_group = base_group.add_mutually_exclusive_group()                                                                
mutex_group.add_argument("-v", "--verbose", action="store_true", default=False, help="print logs verbosity")           
mutex_group.add_argument("-q", "--quiet", action="store_true", default=False, help="suppress every normal output") 

If I use this parser as parent in an other one, then I would like to see in the help the next:

usage: my_program.py [-h] [-l FILE] [-c] [-v | -q ] [<the parent arguments ...>]

Desc...

optional arguments:
   <the my_program.py arguments>

global arguments:
  -l FILE, --log-file FILE
                    set log file (default no log)
  -c, --clear-log       clear log file before logging
  -v, --verbose         print logs verbosity
  -q, --quiet           suppress every normal output

But unfortunately the arguments from mutex group (-v and -q) are shown in "optional arguments" part. Why? Is it a bug? Or do I make something wrongly?

UPDATE:

I created a bug for this problem: http://bugs.python.org/issue25882. See this bug for my simple code and its output for this situation.

Regisz
  • 481
  • 9
  • 17
  • Mutually exclusive argument groups aren't named, they are always shown in their parent group (here "global arguments") (see, e.g., the output in [this](http://stackoverflow.com/questions/7869345/how-to-make-python-argparse-mutually-exclusive-group-arguments-without-prefix) – hlt Dec 16 '15 at 10:03
  • @hlt but in this case the parent group is the "base_group", isn't? – Regisz Dec 16 '15 at 10:11
  • I think you misunderstand me :). The output in my question would be the good solution for me, but not this is happened. The -v and -q are shown in "optional arguments" part in what the arguments of child parser are shown. I would like if -v and -q could be seen in "global arguments" what is the arguments of parent parser. – Regisz Dec 16 '15 at 10:17
  • It works for me on 2.7.9... odd. – hlt Dec 16 '15 at 10:19
  • my python version is 2.7.3, maybe then this is a bug ... I will try to check it in checklogs of python, thx the checking @hlt – Regisz Dec 16 '15 at 10:22

1 Answers1

1

parent_parser behaves as you want, but when used as a parents it does not.

If I add to your code (correcting a use of parser):

parent_parser.print_help()

print('-------------')
parser=argparse.ArgumentParser(parents=[parent_parser])
parser.print_help()

I get (in all versions)

1317:~/mypy$ python3.5 stack34308904.py 
usage: stack34308904.py [-l FILE] [-c] [-v | -q]

global arguments:
  -l FILE, --log-file FILE
                        set log file (default no log)
  -c, --clear-log       clear log file before logging
  -v, --verbose         print logs verbosity
  -q, --quiet           suppress every normal output
-------------
usage: stack34308904.py [-h] [-l FILE] [-c] [-v | -q]

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         print logs verbosity
  -q, --quiet           suppress every normal output

global arguments:
  -l FILE, --log-file FILE
                        set log file (default no log)
  -c, --clear-log       clear log file before logging

It's evident from comments in the '_add_container_actions' method (the method that copies groups and arguments from a parent to a child), that the developers anticipated the situation where a mutually_exclusive_group was embedded in an argument_group, but haven't yet tried to get that working correctly.

The simplest immediate fix is to skip the parents bit, and just define the groups and arguments in the main parser. parents are a convenience in some cases (and a nuisance in others), but rarely necessary.


There is now a bug/issue;

A tentative fix is to add 2 lines to argparse._ActionsContainer._add_container_actions

....
# add container's mutually exclusive groups
# NOTE: if add_mutually_exclusive_group ever gains title= and
# description= then this code will need to be expanded as above
for group in container._mutually_exclusive_groups:
    #print('container title',group._container.title)
    mutex_group = self.add_mutually_exclusive_group(
        required=group.required)
    # new lines - updates the `_container attribute of the new mx group
    mx_container = title_group_map[group._container.title]
    mutex_group._container = mx_container

http://bugs.python.org/issue25882 - issue with a monkey patch file.

hpaulj
  • 221,503
  • 14
  • 230
  • 353