Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

argparse group nesting lost on inheritance #61011

Open
dougalsutherland mannequin opened this issue Dec 29, 2012 · 5 comments
Open

argparse group nesting lost on inheritance #61011

dougalsutherland mannequin opened this issue Dec 29, 2012 · 5 comments
Labels
3.9 only security fixes 3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@dougalsutherland
Copy link
Mannequin

dougalsutherland mannequin commented Dec 29, 2012

BPO 16807
Nosy @dougalsutherland, @iritkatriel
Files
  • argparse_mutex_parent.patch: patch fixing the problem and adding a test
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2012-12-29.01:39:27.035>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = 'argparse group nesting lost on inheritance'
    updated_at = <Date 2021-12-10.16:54:57.102>
    user = 'https://github.com/dougalsutherland'

    bugs.python.org fields:

    activity = <Date 2021-12-10.16:54:57.102>
    actor = 'iritkatriel'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2012-12-29.01:39:27.035>
    creator = 'dougalsutherland'
    dependencies = []
    files = ['28473']
    hgrepos = []
    issue_num = 16807
    keywords = ['patch']
    message_count = 5.0
    messages = ['178459', '222934', '223047', '223158', '408222']
    nosy_count = 4.0
    nosy_names = ['bethard', 'paul.j3', 'dougalsutherland', 'iritkatriel']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue16807'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    @dougalsutherland
    Copy link
    Mannequin Author

    dougalsutherland mannequin commented Dec 29, 2012

    If you wrap a mutually exclusive group inside an argument group in an argparse.ArgumentParser, and then use parents= to inherit from that parser, the non-exclusive argument group is forgotten in the help output, and the arguments move to the default "optional arguments" section. For example:

        # construct the parser with a mutually exclusive group
        >>> import argparse
        >>> parent = argparse.ArgumentParser(add_help=False)
        >>> group = parent.add_argument_group('the group')
        >>> group.add_argument('--foo') and None
        >>> mutex = group.add_mutually_exclusive_group()
        >>> mutex.add_argument('-a', action='store_true') and None
        >>> mutex.add_argument('-b', action='store_true') and None
        >>> parent.print_help()
        usage: [--foo FOO] [-a | -b]
    the group:
      --foo FOO
      -a
      -b
    
        # now try to inherit from it; "the group" is forgotten for
        # mutex arguments, but remains for others
        >>> argparse.ArgumentParser(add_help=False, parents=[parent]).print_help()
        usage: [--foo FOO] [-a | -b]
    optional arguments:
      -a
      -b
    
    the group:
      --foo FOO
    

    I see the same behavior on 2.7.3 and 3.3.0.

    The problem is that argparse._ActionsContainer._add_container_actions always adds mutex groups to the top level, rather than to the equivalent of their _container attribute. The attached patch fixes this, and adds a test based on the formatted output (almost identical to the test_groups_parents test).

    One thing about the patch: it assumes that the _container attribute of all the mutex groups will be either the container argument to _add_container_actions or an argument group that has been processed in group_map. If this is not the case, it'll fail with either an AttributeError or a KeyError. I don't know when this would happen, or if it's common enough that it's worth checking for more explicitly.

    @dougalsutherland dougalsutherland mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Dec 29, 2012
    @BreamoreBoy
    Copy link
    Mannequin

    BreamoreBoy mannequin commented Jul 13, 2014

    @dougal sorry about the delay in getting back to you.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Jul 14, 2014

    To put this issue in perspective:

    • There's nothing in the documentation about nesting a mutually exclusive group in an argument group.

    • There are prominent notes in the documentation about MEGs not taking title and description. The '_add_container_actions' code has a warning that something needs to change if they do acquire such attributes.

    • However there is a class in test_argparse.py that does nest an MEG in an argument group, which in effect gives it a title.
      TestMutuallyExclusiveInGroup
      That's the pattern that Dougal is using.

    • http://bugs.python.org/issue17218 support title and description in argparse add_mutually_exclusive_group

    proposes adding these attributes to MEG. There I proposed doing so via this nested group mechanism. So that patch requires this one to work correctly with parents.

    • http://bugs.python.org/issue11588 I am exploring the implementation of UsageGroups, a generalization of MEG that allow other group tests, and nesting. There too title and description come via nesting in an ArgumentGroup.

    • Groups and parents are confusing to beginning users. In StackOverflow questions 'argparse' users often confuse argument groups and mutually exclusive groups, expecting to be able to nest one inside the other. Currently that nesting only works one way, and for the limited purpose illustrated here.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Jul 15, 2014

    The subcommands grouping mechanism proposed in http://bugs.python.org/issue9341
    probably does not work with [parents] either.

    This _add_container_actions method is brittle. It has to know too much about the structure of a parser and its groups. Any change to that structure could break this [parents] mechanism.

    In a refactoring, each 'add_xxx' method would have a 'copy_xxx' companion method.

    @iritkatriel
    Copy link
    Member

    Reproduced on 3.11:

    >>> argparse.ArgumentParser(add_help=False, parents=[parent]).print_help()
    usage: [--foo FOO] [-a | -b]

    options:
    -a
    -b

    the group:
    --foo FOO

    @iritkatriel iritkatriel added 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Dec 10, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 only security fixes 3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    Status: Bugs
    Development

    No branches or pull requests

    1 participant