Skip to content

Support of mutually exclusive groups in the argparse help is very limited #142346

Closed

Description

@serhiy-storchaka

Bug report

argparse supports grouping mutually exclusive arguments in the usage. For example:

import argparse
parser = argparse.ArgumentParser(prog="PROG")
group = parser.add_mutually_exclusive_group()
group.add_argument('-f', action='store_true')
group.add_argument('x', nargs='?')
print(parser.format_usage())

Output:

usage: PROG [-h] [-f | x]

But it does not work if there is a positional argument before a mutually exclusive group containing positional argument:

import argparse
parser = argparse.ArgumentParser(prog="PROG")
parser.add_argument('x')
group = parser.add_mutually_exclusive_group()
group.add_argument('-f', action='store_true')
group.add_argument('y', nargs='?')
print(parser.format_usage())

Output:

usage: PROG [-h] [-f] x [y]

Expected output:

usage: PROG [-h] x [-f | y]

Or there is an optional argument after a mutually exclusive group:

import argparse
parser = argparse.ArgumentParser(prog="PROG")
group = parser.add_mutually_exclusive_group()
group.add_argument('-f', action='store_true')
group.add_argument('x', nargs='?')
parser.add_argument('-g', action='store_true')
print(parser.format_usage())

Output:

usage: PROG [-h] [-f] [-g] [x]

Expected output:

usage: PROG [-h] [-f | x] [-g]

Or there are multiple mutually exclusive groups:

import argparse
parser = argparse.ArgumentParser(prog="PROG")
group1 = parser.add_mutually_exclusive_group()
group1.add_argument('-f', action='store_true')
group1.add_argument('x', nargs='?')
group2 = parser.add_mutually_exclusive_group()
group2.add_argument('-g', action='store_true')
group2.add_argument('y', nargs='?')
print(parser.format_usage())

Output:

usage: PROG [-h] [-f] [-g] [x] [y]

Expected output:

usage: PROG [-h] [-f | x] [-g | y]

(or something like).

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    type-featureA feature request or enhancement
    stdlibStandard Library Python modules in the Lib/ directory
    3.13only security fixes
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Dec 6, 2025
  2. added 2 commits that reference this issue on Dec 7, 2025
  3. added a commit that references this issue on Dec 7, 2025
  4. added a commit that references this issue on Dec 7, 2025
  5. serhiy-storchaka commented on Dec 8, 2025

    @serhiy-storchaka
    MemberAuthor

    It cannot be backported to 3.13 because the new algorithm does not work with nested mutually exclusive groups, which were deprecated and removed in 3.14.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.14bugs and security fixes3.15bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errortype-featureA feature request or enhancement

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions