This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author paul.j3
Recipients caveman, eric.smith, louielu, paul.j3
Date 2017-10-12.20:52:05
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1507841525.4.0.213398074469.issue31768@psf.upfronthosting.co.za>
In-reply-to
Content
I've changed your example a bit to clarify some points.

    parser.add_argument('n', type=int)
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-v", "--verbose", action="store_true")
    group.add_argument("-q", "--quiet", action="store_true")
    group.add_argument("-x", metavar='X', type=str, help="the base", nargs='?')
    group.add_argument("-y", metavar='Y', type=str, help="the exponent", nargs='?')

    for i in range(int(sys.argv[1])):
         group.add_argument("z%s"%i, nargs='?')

With `n=0`, usage is:

    usage: PROG [-h] [-v | -q | -x [X] | -y [Y]] n

Notice that the positional is placed last.  That is, regardless of the definition order, 'usage' shows optionals first, positionals last.

With 2 'z':

    usage: PROG [-h] [-v] [-q] [-x [X]] [-y [Y]] n [z0] [z1]

All the mutually exclusive markings have been dropped.  That's because the component actions are not consecutive, having been split up by the reordering of positionals.  Marking the group is done only if it can do so in a simple minded way.  The group testing is not dependent on being able to format it.  That's done by a different part of the code.

For 7 'z' it splits the line.  Positionals are printed on a new line.

    usage: PROG [-h] [-v] [-q] [-x [X]] [-y [Y]]
                n [z0] [z1] [z2] [z3] [z4] [z5] [z6]


I noticed this problem with formating group positional in multiline usage some time ago, https://bugs.python.org/issue10984#msg192954


Another thing to watch out for - multiple positionals in a group don't make sense.  Only the first one can ever be filled.  I don't see a formal check, but it doesn't make logical sense.

If I change the code so it produces multiple optionals:

    usage: PROG [-h] [-v | -q | -x X | -y Y | --z0 [Z0] | --z1 [Z1] | --z2 [Z2] |
                --z3 [Z3] | --z4 [Z4]]
                n

the group markings are preserved across lines.  Note again that the positional (n) is on its own line.

---

Here's another weird behavior, with just one positional in the group:

    1314:~/mypy$ python3 argdev/issue31768.py 1 -v 3
    usage: PROG [-h] [-v] [-q] [-x X] [-y Y] n [z0]
    PROG: error: unrecognized arguments: 3

It complains about not recognizing the '3', rather than complaining about 'z0' not allow with '-v'.  That's because the '?' has already been satisfied with [] when parsing the 'n' (see https://bugs.python.org/issue15112).

---

In sum, I think this is pathological case that doesn't need to be fixed.  

Usage is ok if there's a long list of optionals.  Usage (and parsing) with just one positional in the group is brittle.  We shouldn't expect it work with many positionals in the group.

---

@Louie, you 2nd example interweaves the definitions of two groups.  Except for the optionals/positions reordering that I mentioned above, usage does not reorder arguments.  Mutually exclusive groups are marked only if they are contiguous.  

https://bugs.python.org/issue10984 has a patch that can format groups even if the actions don't occur in the right order.  It isn't a trivial fix.
History
Date User Action Args
2017-10-12 20:52:05paul.j3setrecipients: + paul.j3, eric.smith, louielu, caveman
2017-10-12 20:52:05paul.j3setmessageid: <1507841525.4.0.213398074469.issue31768@psf.upfronthosting.co.za>
2017-10-12 20:52:05paul.j3linkissue31768 messages
2017-10-12 20:52:05paul.j3create