Skip to content

Commit 93daa90

Browse files
committed
argparse subnamespace: Add documentation of subnamespace feature
1 parent 76edae9 commit 93daa90

1 file changed

Lines changed: 69 additions & 4 deletions

File tree

Doc/library/argparse.rst

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

19352000
FileType objects
19362001
^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)