@@ -1716,8 +1716,9 @@ Subcommands
17161716 :meth: `!add_subparsers ` method. The :meth: `!add_subparsers ` method is normally
17171717 called with no arguments and returns a special action object. This object
17181718 has a single method, :meth: `~_SubParsersAction.add_parser `, which takes a
1719- command name and any :class: `!ArgumentParser ` constructor arguments, and
1720- returns an :class: `!ArgumentParser ` object that can be modified as usual.
1719+ command name, optional deprecated _ and subnamespace _ flags, any
1720+ :class: `!ArgumentParser ` constructor arguments, and returns an
1721+ :class: `!ArgumentParser ` object that can be modified as usual.
17211722
17221723 Description of parameters:
17231724
@@ -1775,7 +1776,9 @@ Subcommands
17751776 command line (and not any other subparsers). So in the example above, when
17761777 the ``a `` command is specified, only the ``foo `` and ``bar `` attributes are
17771778 present, and when the ``b `` command is specified, only the ``foo `` and
1778- ``baz `` attributes are present.
1779+ ``baz `` attributes are present. If one wishes to store the the subparser's
1780+ attributes separate from the main parser's attributes, see the subnamespace _
1781+ option of :meth: `~_SubParsersAction.add_parser `.
17791782
17801783 Similarly, when a help message is requested from a subparser, only the help
17811784 for that particular parser will be printed. The help message will not
@@ -1896,7 +1899,8 @@ Subcommands
18961899
18971900
18981901.. method :: _SubParsersAction.add_parser(name, *, help=None, aliases=None, \
1899- deprecated=False, **kwargs)
1902+ deprecated=False, subnamespace=False, \
1903+ **kwargs)
19001904
19011905 Create and return a new :class: `ArgumentParser ` object for the
19021906 subcommand *name *.
@@ -1925,12 +1929,73 @@ Subcommands
19251929 chicken.py: warning: command 'fly' is deprecated
19261930 Namespace()
19271931
1932+ .. _subnamespace :
1933+
1934+ The *subnamespace * flag, if ``True ``, tells the parent parser to
1935+ store the subparser's parsed arguments contained in
1936+ their own :class: `Namespace `, nested within the parent's :class: `!Namespace `.
1937+ The attribute name in the parent's namespace at which the
1938+ subparser's subnamespace is stored is the subparser's *name *,
1939+ but with underscores ``_ `` replacing hyphens ``- ``
1940+ similar to dest _ in :meth: `ArgumentParser.add_argument `.
1941+
1942+ This is useful for receiving parsed arguments hierarchically, mirroring the
1943+ hierarchical relation between a parser and its subparsers. For example::
1944+
1945+ >>> inet = argparse.ArgumentParser(add_help=False)
1946+ >>> inet.add_argument("address")
1947+ >>> inet.add_argument("port", type=int)
1948+ >>>
1949+ >>> unix = argparse.ArgumentParser(add_help=False)
1950+ >>> unix.add_argument("path")
1951+ >>>
1952+ >>> parser = argparse.ArgumentParser(prog='my-socat')
1953+ >>> action = parser.add_subparsers(required=True, dest="action")
1954+ >>>
1955+ >>> parser_bind = action.add_parser("bind", subnamespace=True)
1956+ >>> parser_bind.add_argument("--fork", action="store_true")
1957+ >>> bind_family = parser_bind.add_subparsers(required=True, dest="family")
1958+ >>>
1959+ >>> parser_bind_inet = bind_family.add_parser("inet", subnamespace=True, parents=[inet])
1960+ >>> parser_bind_unix = bind_family.add_parser("unix", subnamespace=True, parents=[unix])
1961+ >>>
1962+ >>> parser_connect = action.add_parser("connect", subnamespace=True)
1963+ >>> connect_family = parser_connect.add_subparsers(required=True, dest="family")
1964+ >>>
1965+ >>> parser_connect_inet = connect_family.add_parser("inet", subnamespace=True, parents=[inet])
1966+ >>> parser_connect_unix = connect_family.add_parser("unix", subnamespace=True, parents=[unix])
1967+ >>>
1968+ >>> args = parser.parse_args(["bind", "unix", "/foo/bar/socket"])
1969+ >>> args
1970+ Namespace(action='bind', bind=Namespace(fork=False, family='unix', unix=Namespace(path='/foo/bar/socket')))
1971+
1972+ This is also very useful when one has arguments in subparsers whose
1973+ ``dest `` conflict with those of the parent parser's arguments, and one
1974+ wishes to faithfully distinguish between the two. For example::
1975+
1976+ >>> parser = argparse.ArgumentParser(prog='restaurant.py')
1977+ >>> parser.add_argument('-f', help='fast-tracked order', action='store_true')
1978+ >>> meals = parser.add_subparsers(dest='meal')
1979+ >>>
1980+ >>> parser_nuggets = meals.add_parser('chicken-nuggets', subnamespace=True)
1981+ >>> parser_nuggets.add_argument('-f', help='with fries', action='store_true')
1982+ >>>
1983+ >>> parser_salad = meals.add_parser('caesar-salad', subnamespace=True)
1984+ >>> parser_salad.add_argument('-f', help='fresh', action='store_true')
1985+ >>>
1986+ >>> args = parser.parse_args(['chicken-nuggets', '-f'])
1987+ >>> args
1988+ Namespace(f=False, meal='chicken-nuggets', chicken_nuggets=Namespace(f=True))
1989+
19281990 All other keyword arguments are passed directly to the
19291991 :class: `!ArgumentParser ` constructor.
19301992
19311993 .. versionadded :: 3.13
19321994 Added the *deprecated * parameter.
19331995
1996+ .. versionadded :: next
1997+ Added the *subnamespace * parameter.
1998+
19341999
19352000FileType objects
19362001^^^^^^^^^^^^^^^^
0 commit comments