11"""Build argparse parsers from type-annotated function signatures.
22
3- .. warning:: Experimental
3+ !!! warning " Experimental"
44
5- This module is experimental and its behavior may change in future releases.
5+ This module is experimental and its behavior may change in future releases.
66
7- The :func: `with_annotated` decorator inspects a command function's type hints and
8- default values to build a ``Cmd2ArgumentParser``. :class: `Argument` and
9- :class: `Option` metadata classes give finer per-parameter control via
7+ The [ `with_annotated`][cmd2.annotated.with_annotated] decorator inspects a command function's type hints and
8+ default values to build a ``Cmd2ArgumentParser``. [ `Argument`][cmd2.annotated.Argument] and
9+ [ `Option`][cmd2.annotated.Option] metadata classes give finer per-parameter control via
1010``typing.Annotated``.
1111
1212Parameters without defaults become positional arguments; parameters with defaults
1818flag (``dry_run`` -> ``--dry-run``); pass an explicit ``Option("--my_flag")`` to opt out.
1919Positional-only parameters (before ``/``) and ``**kwargs`` raise ``TypeError``. The parameter
2020names ``dest`` and ``subcommand`` are reserved; ``cmd2_statement`` receives the parsed
21- ``Statement`` and (with ``base_command=True``) ``cmd2_handler`` receives the subcommand handler::
21+ ``Statement`` and (with ``base_command=True``) ``cmd2_handler`` receives the subcommand handler:
2222
2323 class MyApp(cmd2.Cmd):
2424 @cmd2.with_annotated
@@ -27,8 +27,8 @@ def do_greet(self, name: str, count: int = 1, loud: bool = False):
2727 msg = f"Hello {name}"
2828 self.poutput(msg.upper() if loud else msg)
2929
30- Use ``Annotated`` with :class: `Argument` or :class: `Option` for finer
31- control over individual parameters::
30+ Use ``Annotated`` with [ `Argument`][cmd2.annotated.Argument] or [ `Option`][cmd2.annotated.Option] for finer
31+ control over individual parameters:
3232
3333 from typing import Annotated
3434
@@ -84,7 +84,7 @@ def do_paint(
8484 converted ``VALUE``); the ``const`` is stored verbatim and must match the declared type.
8585 ``const`` is validated against the declared type and is rejected on a positional ``Argument`` (argparse
8686 ignores it there)
87- - a custom :class: `argparse.Action` subclass -- passed straight through to ``add_argument``.
87+ - a custom `argparse.Action` subclass -- passed straight through to ``add_argument``.
8888 The user's class owns storage, so the collection-casting wrapper is dropped and the action-specific
8989 type/const/collection-shape constraints are skipped. The type-inferred converter, default, and
9090 ``required`` are still applied; the action receives them like any hand-built ``add_argument`` call.
@@ -106,20 +106,20 @@ def do_paint(
106106parameter, which maps to it -- a raw ``help`` would silently shadow it), and -- on ``Argument`` only
107107-- ``action`` / ``required`` (which have no meaning on a positional). Every other ``add_argument``
108108parameter, including those registered via
109- :func:`~ cmd2.argparse_utils.register_argparse_argument_parameter` , passes through unchanged.
109+ [`register_argparse_argument_parameter`][ cmd2.argparse_utils.register_argparse_argument_parameter] , passes through unchanged.
110110
111111A ``default`` may be supplied either as the function-signature default (``param: T = v``) or as
112112``Argument(default=v)`` / ``Option(default=v)`` -- the two forms are equivalent. Specifying both at
113113once raises ``TypeError`` (the value would have two sources of truth), and ``argparse.SUPPRESS`` is
114114rejected as a default from either source because it would remove the keyword argument the function
115115expects.
116116
117- Parser-level customization is forwarded to :class:`~ cmd2.Cmd2ArgumentParser` 's constructor via PEP
117+ Parser-level customization is forwarded to [`Cmd2ArgumentParser`][ cmd2.argparse_utils. Cmd2ArgumentParser] 's constructor via PEP
118118692 ``**parser_kwargs: Unpack[Cmd2ParserKwargs]``. Anything the parser ctor accepts -- ``description``,
119119``epilog``, ``prog``, ``usage``, ``parents``, ``argument_default``, ``prefix_chars``,
120120``fromfile_prefix_chars``, ``conflict_handler``, ``add_help``, ``allow_abbrev``, ``exit_on_error``,
121121``formatter_class``, ``ap_completer_type``, and on Python >= 3.14 ``suggest_on_error`` / ``color`` --
122- flows straight through; the :class: `Cmd2ParserKwargs` ``TypedDict`` is the single source of truth
122+ flows straight through; the [ `Cmd2ParserKwargs`][cmd2.annotated.Cmd2ParserKwargs] ``TypedDict`` is the single source of truth
123123and gives type-checkers/IDEs autocomplete on the decorator's call site. ``parser_class`` stays as
124124its own explicit kwarg because it selects the class itself, not a value passed to it. Two
125125behaviors layer on top of the raw passthrough: if ``description`` is omitted, the first paragraph
@@ -218,7 +218,7 @@ def do_paint(
218218
219219
220220class Cmd2ParserKwargs (TypedDict , total = False ):
221- """Forwarded ctor kwargs for :class:`~ cmd2.Cmd2ArgumentParser` (PEP 692 ``Unpack``).
221+ """Forwarded ctor kwargs for [`Cmd2ArgumentParser`][ cmd2.argparse_utils. Cmd2ArgumentParser] (PEP 692 ``Unpack``).
222222
223223 Single source of truth mirroring the parser's ``__init__``: add a field here to expose a new
224224 ctor kwarg on the decorator's call site. All optional (``total=False``); ``suggest_on_error``
@@ -302,7 +302,7 @@ def __init__(
302302 ``default`` mirrors the signature default (``Option(default=v)`` == ``... = v``); supplying
303303 both, or ``argparse.SUPPRESS``, is rejected. ``extra_kwargs`` forwards any other
304304 ``add_argument`` parameter (incl. those from
305- :func:`~ cmd2.argparse_utils.register_argparse_argument_parameter` ) straight through.
305+ [`register_argparse_argument_parameter`][ cmd2.argparse_utils.register_argparse_argument_parameter] ) straight through.
306306 """
307307 reserved = self ._RESERVED_EXTRA_KWARGS & extra_kwargs .keys ()
308308 if reserved :
@@ -362,7 +362,7 @@ def __init__(
362362
363363 ``action`` is a supported string action (``store_true``/``store_false``/``count``/
364364 ``append``/``extend``/``store_const``/``append_const``) or a custom
365- :class: `argparse.Action` subclass (passed through; it owns storage, so the inferred
365+ `argparse.Action` subclass (passed through; it owns storage, so the inferred
366366 action and the action-specific constraints are skipped).
367367 """
368368 super ().__init__ (** kwargs )
@@ -1940,16 +1940,16 @@ def build_parser_from_function(
19401940) -> Cmd2ArgumentParser :
19411941 """Inspect a function's signature and build a ``Cmd2ArgumentParser``.
19421942
1943- The lower-level entry point behind :func: `with_annotated`. ``parser_kwargs`` is forwarded to
1944- the parser ctor (see :class: `Cmd2ParserKwargs`); when ``description`` is omitted, the first
1943+ The lower-level entry point behind [ `with_annotated`][cmd2.annotated.with_annotated] . ``parser_kwargs`` is forwarded to
1944+ the parser ctor (see [ `Cmd2ParserKwargs`][cmd2.annotated.Cmd2ParserKwargs] ); when ``description`` is omitted, the first
19451945 paragraph of ``func.__doc__`` is used.
19461946
19471947 :param func: the command function to inspect
19481948 :param skip_params: parameter names to exclude from the parser
1949- :param groups: :class: `Group` instances assigning parameters to argument groups
1950- :param mutually_exclusive_groups: :class: `Group` instances of mutually exclusive parameters
1949+ :param groups: [ `Group`][cmd2.annotated.Group] instances assigning parameters to argument groups
1950+ :param mutually_exclusive_groups: [ `Group`][cmd2.annotated.Group] instances of mutually exclusive parameters
19511951 :param parser_class: custom parser class (defaults to the configured default)
1952- :param parser_kwargs: forwarded :class: `Cmd2ParserKwargs`
1952+ :param parser_kwargs: forwarded [ `Cmd2ParserKwargs`][cmd2.annotated.Cmd2ParserKwargs]
19531953 :return: a fully configured ``Cmd2ArgumentParser``
19541954 """
19551955 parser_cls = parser_class or DEFAULT_ARGUMENT_PARSER
@@ -2175,14 +2175,15 @@ def with_annotated(
21752175 :param help: subcommand help text (only with ``subcommand_to``)
21762176 :param aliases: alternative subcommand names (only with ``subcommand_to``)
21772177 :param deprecated: mark the subcommand deprecated in ``--help`` (only with ``subcommand_to``)
2178- :param groups: :class: `Group` instances assigning parameters to titled argument groups
2179- :param mutually_exclusive_groups: :class: `Group` instances of mutually exclusive parameters
2178+ :param groups: [ `Group`][cmd2.annotated.Group] instances assigning parameters to titled argument groups
2179+ :param mutually_exclusive_groups: [ `Group`][cmd2.annotated.Group] instances of mutually exclusive parameters
21802180 :param parser_class: custom parser class (defaults to the configured default)
21812181 :param subcommand_required: whether a subcommand must be supplied (``base_command`` only)
21822182 :param subcommand_metavar: metavar for the subcommands group (``base_command`` only)
21832183 :param subcommand_title: title for the subcommands ``--help`` section (``base_command`` only)
21842184 :param subcommand_description: description for that section (``base_command`` only)
2185- :param parser_kwargs: any :class:`~cmd2.Cmd2ArgumentParser` ctor kwarg (see :class:`Cmd2ParserKwargs`).
2185+ :param parser_kwargs: any [`Cmd2ArgumentParser`][cmd2.argparse_utils.Cmd2ArgumentParser] ctor kwarg
2186+ (see [`Cmd2ParserKwargs`][cmd2.annotated.Cmd2ParserKwargs]).
21862187 ``description`` defaults to the docstring's first paragraph when omitted;
21872188 ``prog`` is rejected with ``subcommand_to`` (cmd2 rewrites it from the parent).
21882189 """
0 commit comments