Author paul.j3
Recipients John.Didion, bethard, manveru, paul.j3, xuanji
Date 2014-06-13.04:36:45
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
I have developed a UsageGroup class that can implement nested 'inclusive' tests.  Using this, the original example in this issue could be coded as 3 groups, 2 mutually_exclusive and inclusive one.

    parser = ArgumentParser(prog='PROG', formatter_class=UsageGroupHelpFormatter)

    g1 = parser.add_usage_group(dest='FILE or DIR', kind='mxg', required=True)
    a_file= g1.add_argument("-o", "--outfile", metavar='FILE')

    g2 = g1.add_usage_group(dest='DIR and PS', kind='inc')
    a_dir = g2.add_argument("-O", "--outdir", metavar='DIR')

    g3 = g2.add_usage_group(dest='P or S', kind='mxg')
    a_pat = g3.add_argument("-p", "--outpattern", metavar='PATTERN')
    a_suf = g3.add_argument("-s", "--outsuffix", metavar='SUFFIX')
    # usage: PROG [-h] (-o FILE | (-O DIR & (-p PATTERN | -s SUFFIX)))

UsageGroup is like MutuallyExclusiveGroup, except that:

- A nested group is added to self._group_actions, but its actions are not.  Those actions are added separately to the parser._actions list.  Thus the '_group_actions' list can be a mix of actions and groups.

- Each group has a 'testfn', a function that tests its own '_group_actions' against the 'seen_non_default_actions' provided by the parser. These are similar to the 'cross_test' functions I developed
earlier.  The 'testfn' for primary level usage groups are registered with cross_tests (here renamed 'usage_tests')).  'testfn' for nested groups are handled recursively in the containing testfn.

- Normally 'testfn' is chosen based on 'kind' and 'required' parameters. 'kind' can implement logical actions like 'xor' (mutually exclusive), 'and' (inclusive), 'or' (any), 'not'.  These seem to cover most possibilities, though custom tests are possible.

- Each group has several variables defining how it is to be formatted.  The basic ones are 'joiner' (e.g. '|&^,') and 'parens' (e.g. (),[],{}).  Or a totally custom 'usage' string could be used.

- The Usage Formatter is a derivative of the MultiGroupHelpFormatter I wrote for issue 10984.  Each group is formatted individually (and possibly recursively).

- Existing actions and usage groups can be added to a usage group.  This adds to the flexibility of the usage testing, though the formatted usage line could easily become unwieldy.

- A 'mxg' UsageGroup effectively replaces a MutuallyExclusiveGroup.

- self._add_container_actions(parent) knows nothing about this class yet.

The attached '' file has the core code for this change.  The full working code is at

It incorporates too many other changes (from other bug issues) to post
here as a simple patch file (yet).  I have a number of test scripts, but haven't cast those as unittests.  Same goes for documentation.
Date User Action Args
2014-06-13 04:36:50paul.j3setrecipients: + paul.j3, bethard, xuanji, John.Didion, manveru
2014-06-13 04:36:49paul.j3setmessageid: <>
2014-06-13 04:36:49paul.j3linkissue11588 messages
2014-06-13 04:36:49paul.j3create