Skip to content

Commit 5413585

Browse files
committed
Renamed set_default_argument_parser_type() to set_default_argument_parser().
Renamed set_default_ap_completer_type() to set_default_argparse_completer(). Renamed Cmd2ArgumentParser.ap_completer_type to completer_class.
1 parent 9cbf99a commit 5413585

10 files changed

Lines changed: 75 additions & 78 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ prompt is displayed.
6767
- Removed `Cmd.ruler` since `cmd2` no longer uses it.
6868
- All parsers used with `cmd2` commands must be an instance of `Cmd2ArgumentParser` or a child
6969
class of it.
70-
- Removed `set_ap_completer_type()` and `get_ap_completer_type()` since `ap_completer_type` is
71-
now a public member of `Cmd2ArgumentParser`.
70+
- Renamed `set_default_argument_parser_type()` to `set_default_argument_parser()`.
71+
- Renamed `set_default_ap_completer_type()` to `set_default_argparse_completer()`.
72+
- Removed `set_ap_completer_type()` and `get_ap_completer_type()` since `completer_class` is now
73+
a public member of `Cmd2ArgumentParser`.
7274
- Moved `set_parser_prog()` to `Cmd2ArgumentParser.update_prog()`.
7375
- Renamed `cmd2_handler` to `cmd2_subcommand_func` in the `argparse.Namespace` for clarity.
7476
- Removed `Cmd2AttributeWrapper` class. `argparse.Namespace` objects passed to command functions

cmd2/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
string_utils,
1313
)
1414
from .annotated import with_annotated
15-
from .argparse_completer import set_default_ap_completer_type
15+
from .argparse_completer import set_default_argparse_completer
1616
from .argparse_utils import (
1717
Cmd2ArgumentParser,
1818
SubcommandRecord,
1919
register_argparse_argument_parameter,
20-
set_default_argument_parser_type,
20+
set_default_argument_parser,
2121
)
2222
from .cmd2 import Cmd
2323
from .colors import Color
@@ -75,8 +75,8 @@
7575
"Cmd2ArgumentParser",
7676
"SubcommandRecord",
7777
"register_argparse_argument_parameter",
78-
"set_default_ap_completer_type",
79-
"set_default_argument_parser_type",
78+
"set_default_argparse_completer",
79+
"set_default_argument_parser",
8080
# Cmd2
8181
"Cmd",
8282
"CommandResult",

cmd2/annotated.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def do_paint(
118118
692 ``**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``,
121-
``formatter_class``, ``ap_completer_type``, and on Python >= 3.14 ``suggest_on_error`` / ``color`` --
121+
``formatter_class``, ``completer_class``, and on Python >= 3.14 ``suggest_on_error`` / ``color`` --
122122
flows straight through; the [`Cmd2ParserKwargs`][cmd2.annotated.Cmd2ParserKwargs] ``TypedDict`` is the single source of truth
123123
and gives type-checkers/IDEs autocomplete on the decorator's call site. ``parser_class`` stays as
124124
its own explicit kwarg because it selects the class itself, not a value passed to it. Two
@@ -257,7 +257,7 @@ class Cmd2ParserKwargs(TypedDict, total=False):
257257
exit_on_error: bool
258258
suggest_on_error: bool
259259
color: bool
260-
ap_completer_type: "type[ArgparseCompleter] | None"
260+
completer_class: "type[ArgparseCompleter] | None"
261261

262262

263263
# ---------------------------------------------------------------------------

cmd2/argparse_completer.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,7 @@ def consume_argument(arg_state: _ArgumentState, arg_token: str) -> None:
366366
parent_tokens[action.dest] = [token]
367367

368368
parser = self._subcommand_action.choices[token]
369-
completer_type = self._cmd_app._determine_ap_completer_type(parser)
370-
completer = completer_type(parser, self._cmd_app, parent_tokens=parent_tokens)
369+
completer = parser.completer_class(parser, self._cmd_app, parent_tokens=parent_tokens)
371370
return completer.complete(text, line, begidx, endidx, tokens[token_index + 1 :], cmd_set=cmd_set)
372371

373372
# Invalid subcommand entered, so no way to complete remaining tokens
@@ -668,8 +667,7 @@ def complete_subcommand_help(self, text: str, line: str, begidx: int, endidx: in
668667
for token_index, token in enumerate(tokens):
669668
if token in self._subcommand_action.choices:
670669
parser = self._subcommand_action.choices[token]
671-
completer_type = self._cmd_app._determine_ap_completer_type(parser)
672-
completer = completer_type(parser, self._cmd_app)
670+
completer = parser.completer_class(parser, self._cmd_app)
673671
return completer.complete_subcommand_help(text, line, begidx, endidx, tokens[token_index + 1 :])
674672

675673
if token_index == len(tokens) - 1:
@@ -690,8 +688,7 @@ def print_help(self, tokens: Sequence[str], file: IO[str] | None = None) -> None
690688
if tokens and self._subcommand_action is not None:
691689
parser = self._subcommand_action.choices.get(tokens[0])
692690
if parser is not None:
693-
completer_type = self._cmd_app._determine_ap_completer_type(parser)
694-
completer = completer_type(parser, self._cmd_app)
691+
completer = parser.completer_class(parser, self._cmd_app)
695692
completer.print_help(tokens[1:], file)
696693
return
697694
self._parser.print_help(file)
@@ -800,13 +797,13 @@ def _complete_arg(
800797

801798

802799
# The default ArgparseCompleter class for a cmd2 app
803-
DEFAULT_AP_COMPLETER: type[ArgparseCompleter] = ArgparseCompleter
800+
DEFAULT_ARGPARSE_COMPLETER: type[ArgparseCompleter] = ArgparseCompleter
804801

805802

806-
def set_default_ap_completer_type(completer_type: type[ArgparseCompleter]) -> None:
803+
def set_default_argparse_completer(completer_class: type[ArgparseCompleter]) -> None:
807804
"""Set the default ArgparseCompleter class for a cmd2 app.
808805
809-
:param completer_type: Type that is a subclass of ArgparseCompleter.
806+
:param completer_class: Type that is a subclass of ArgparseCompleter.
810807
"""
811-
global DEFAULT_AP_COMPLETER # noqa: PLW0603
812-
DEFAULT_AP_COMPLETER = completer_type
808+
global DEFAULT_ARGPARSE_COMPLETER # noqa: PLW0603
809+
DEFAULT_ARGPARSE_COMPLETER = completer_class

cmd2/argparse_utils.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,13 @@ def __init__(
728728
suggest_on_error: bool = False,
729729
color: bool = False,
730730
*,
731-
ap_completer_type: type["ArgparseCompleter"] | None = None,
731+
completer_class: type["ArgparseCompleter"] | None = None,
732732
) -> None:
733733
"""Initialize the Cmd2ArgumentParser instance.
734734
735-
:param ap_completer_type: optional parameter which specifies a subclass of ArgparseCompleter for custom completion
736-
behavior on this parser. If this is None or not present, then cmd2 will use
737-
argparse_completer.DEFAULT_AP_COMPLETER when completing this parser's arguments
735+
:param completer_class: optional parameter which specifies a subclass of ArgparseCompleter
736+
for custom completion behavior on this parser. If this is None, then
737+
it will be set to argparse_completer.DEFAULT_ARGPARSE_COMPLETER.
738738
"""
739739
kwargs: dict[str, bool] = {}
740740
if sys.version_info >= (3, 14):
@@ -761,7 +761,11 @@ def __init__(
761761
**kwargs,
762762
)
763763

764-
self.ap_completer_type = ap_completer_type
764+
if completer_class is None:
765+
from . import argparse_completer
766+
767+
completer_class = argparse_completer.DEFAULT_ARGPARSE_COMPLETER
768+
self.completer_class = completer_class
765769

766770
# To assist type checkers, recast these to reflect our usage of rich-argparse.
767771
self.formatter_class: type[Cmd2HelpFormatter]
@@ -1087,11 +1091,11 @@ def _check_value(self, action: argparse.Action, value: Any) -> None:
10871091

10881092

10891093
# Parser type used by cmd2's built-in commands.
1090-
# Set it using cmd2.set_default_argument_parser_type().
1094+
# Set it using cmd2.set_default_argument_parser().
10911095
DEFAULT_ARGUMENT_PARSER: type[Cmd2ArgumentParser] = Cmd2ArgumentParser
10921096

10931097

1094-
def set_default_argument_parser_type(parser_type: type[Cmd2ArgumentParser]) -> None:
1098+
def set_default_argument_parser(parser_class: type[Cmd2ArgumentParser]) -> None:
10951099
"""Set the default Cmd2ArgumentParser class for cmd2's built-in commands.
10961100
10971101
Since built-in commands rely on customizations made in Cmd2ArgumentParser,
@@ -1102,4 +1106,4 @@ def set_default_argument_parser_type(parser_type: type[Cmd2ArgumentParser]) -> N
11021106
See examples/custom_parser.py.
11031107
"""
11041108
global DEFAULT_ARGUMENT_PARSER # noqa: PLW0603
1105-
DEFAULT_ARGUMENT_PARSER = parser_type
1109+
DEFAULT_ARGUMENT_PARSER = parser_class

cmd2/cmd2.py

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ def get_root_parser_and_subcmd_path(self, command: str) -> tuple[Cmd2ArgumentPar
12131213
root_command = tokens[0]
12141214
subcommand_path = tokens[1:]
12151215

1216-
# Search for the base command function and verify it has an argparser defined
1216+
# Search for the base command function and verify it has a parser defined
12171217
command_func = self.get_command_func(root_command)
12181218
if command_func is None:
12191219
raise ValueError(f"Root command '{root_command}' does not exist")
@@ -2449,18 +2449,6 @@ def _redirect_complete(self, text: str, line: str, begidx: int, endidx: int, com
24492449
# Call the command's completer function
24502450
return compfunc(text, line, begidx, endidx)
24512451

2452-
@staticmethod
2453-
def _determine_ap_completer_type(parser: Cmd2ArgumentParser) -> type[argparse_completer.ArgparseCompleter]:
2454-
"""Determine what type of ArgparseCompleter to use on a given parser.
2455-
2456-
If the parser does not have one set, then use argparse_completer.DEFAULT_AP_COMPLETER.
2457-
:param parser: the parser to examine
2458-
:return: type of ArgparseCompleter
2459-
"""
2460-
if parser.ap_completer_type is None:
2461-
return argparse_completer.DEFAULT_AP_COMPLETER
2462-
return parser.ap_completer_type
2463-
24642452
def _perform_completion(
24652453
self, text: str, line: str, begidx: int, endidx: int, custom_settings: utils.CustomCompletionSettings | None = None
24662454
) -> Completions:
@@ -2526,16 +2514,15 @@ def _perform_completion(
25262514
else:
25272515
# There's no completer function, next see if the command uses argparse
25282516
command_func = self.get_command_func(command)
2529-
argparser = None if command_func is None else self.command_parsers.get(command_func)
2517+
parser = None if command_func is None else self.command_parsers.get(command_func)
25302518

2531-
if command_func is not None and argparser is not None:
2519+
if command_func is not None and parser is not None:
25322520
# Get arguments for complete()
25332521
spec: ArgparseCommandSpec = getattr(command_func, constants.ARGPARSE_COMMAND_ATTR_SPEC)
25342522
cmd_set = self.find_commandset_for_command(command)
25352523

25362524
# Create the argparse completer
2537-
completer_type = self._determine_ap_completer_type(argparser)
2538-
completer = completer_type(argparser, self)
2525+
completer = parser.completer_class(parser, self)
25392526

25402527
completer_func = functools.partial(
25412528
completer.complete, tokens=raw_tokens[1:] if spec.preserve_quotes else tokens[1:], cmd_set=cmd_set
@@ -2550,8 +2537,7 @@ def _perform_completion(
25502537
# Otherwise we are completing the command token or performing custom completion
25512538
else:
25522539
# Create the argparse completer
2553-
completer_type = self._determine_ap_completer_type(custom_settings.parser)
2554-
completer = completer_type(custom_settings.parser, self)
2540+
completer = custom_settings.parser.completer_class(custom_settings.parser, self)
25552541

25562542
completer_func = functools.partial(
25572543
completer.complete, tokens=raw_tokens if custom_settings.preserve_quotes else tokens, cmd_set=None
@@ -4274,11 +4260,11 @@ def complete_help_subcommands(
42744260

42754261
# Check if this command uses argparse
42764262
if (command_func := self.get_command_func(command)) is None or (
4277-
argparser := self.command_parsers.get(command_func)
4263+
parser := self.command_parsers.get(command_func)
42784264
) is None:
42794265
return Completions()
42804266

4281-
completer = argparse_completer.DEFAULT_AP_COMPLETER(argparser, self)
4267+
completer = parser.completer_class(parser, self)
42824268
return completer.complete_subcommand_help(text, line, begidx, endidx, arg_tokens["subcommands"])
42834269

42844270
def _build_command_info(self) -> tuple[dict[str, list[str]], list[str]]:
@@ -4382,11 +4368,11 @@ def do_help(self, args: argparse.Namespace) -> None:
43824368
return
43834369

43844370
command_func = self.get_command_func(args.command)
4385-
argparser = None if command_func is None else self.command_parsers.get(command_func)
4371+
parser = None if command_func is None else self.command_parsers.get(command_func)
43864372

43874373
# If the command function uses argparse, then use argparse's help
4388-
if command_func is not None and argparser is not None:
4389-
completer = argparse_completer.DEFAULT_AP_COMPLETER(argparser, self)
4374+
if command_func is not None and parser is not None:
4375+
completer = parser.completer_class(parser, self)
43904376
completer.print_help(args.subcommands, self.stdout)
43914377

43924378
# If the command has a custom help function, then call it
@@ -4700,7 +4686,7 @@ def complete_set_value(
47004686
completer=settable.completer,
47014687
)
47024688

4703-
completer = argparse_completer.DEFAULT_AP_COMPLETER(settable_parser, self)
4689+
completer = settable_parser.completer_class(settable_parser, self)
47044690

47054691
# Use raw_tokens since quotes have been preserved
47064692
_, raw_tokens = self.tokens_for_completion(line, begidx, endidx)

docs/features/annotated.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ annotated decorator picks it up automatically.
308308

309309
The forwarded kwargs are `description`, `epilog`, `prog`, `usage`, `parents`, `argument_default`,
310310
`prefix_chars`, `fromfile_prefix_chars`, `conflict_handler`, `add_help`, `allow_abbrev`,
311-
`exit_on_error`, `formatter_class`, `ap_completer_type`, and on Python ≥ 3.14 `suggest_on_error` /
311+
`exit_on_error`, `formatter_class`, `completer_class`, and on Python ≥ 3.14 `suggest_on_error` /
312312
`color`. Two of them layer extra behavior on top of the raw passthrough:
313313

314314
- `description` -- when omitted, it is filled from the function's docstring (detailed below); pass

examples/custom_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Cmd2ArgumentParser,
1010
Cmd2Style,
1111
cmd2,
12-
set_default_argument_parser_type,
12+
set_default_argument_parser,
1313
stylize,
1414
)
1515

@@ -46,7 +46,7 @@ def error(self, message: str) -> NoReturn:
4646
import sys
4747

4848
# Set the default parser type before instantiating app.
49-
set_default_argument_parser_type(CustomParser)
49+
set_default_argument_parser(CustomParser)
5050

5151
app = cmd2.Cmd(include_ipy=True, persistent_history_file="cmd2_history.dat")
5252
app.self_in_py = True # Enable access to "self" within the py command

tests/test_annotated.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,41 +1100,43 @@ class MyParser(cmd2.Cmd2ArgumentParser):
11001100
parser = build_parser_from_function(_make_func(str), parser_class=MyParser)
11011101
assert isinstance(parser, MyParser)
11021102

1103-
def test_ap_completer_type(self) -> None:
1103+
def test_completer_class(self) -> None:
11041104
from cmd2.argparse_completer import ArgparseCompleter
11051105

11061106
class MyCompleter(ArgparseCompleter):
11071107
pass
11081108

1109-
parser = build_parser_from_function(_make_func(str), ap_completer_type=MyCompleter)
1110-
assert parser.ap_completer_type is MyCompleter
1109+
parser = build_parser_from_function(_make_func(str), completer_class=MyCompleter)
1110+
assert parser.completer_class is MyCompleter
11111111

1112-
def test_ap_completer_type_defaults_to_none(self) -> None:
1113-
assert build_parser_from_function(_make_func(str)).ap_completer_type is None
1112+
def test_default_completer_class(self) -> None:
1113+
from cmd2 import argparse_completer
11141114

1115-
def test_ap_completer_type_via_decorator(self) -> None:
1115+
assert build_parser_from_function(_make_func(str)).completer_class is argparse_completer.DEFAULT_ARGPARSE_COMPLETER
1116+
1117+
def test_completer_class_via_decorator(self) -> None:
11161118
from cmd2.argparse_completer import ArgparseCompleter
11171119

11181120
class MyCompleter(ArgparseCompleter):
11191121
pass
11201122

1121-
@with_annotated(ap_completer_type=MyCompleter)
1123+
@with_annotated(completer_class=MyCompleter)
11221124
def do_run(self, name: str) -> None: ...
11231125

11241126
builder = getattr(do_run, constants.ARGPARSE_COMMAND_ATTR_SPEC).parser_source
1125-
assert builder().ap_completer_type is MyCompleter
1127+
assert builder().completer_class is MyCompleter
11261128

1127-
def test_ap_completer_type_threads_to_subcommand(self) -> None:
1129+
def test_completer_class_threads_to_subcommand(self) -> None:
11281130
from cmd2.argparse_completer import ArgparseCompleter
11291131

11301132
class MyCompleter(ArgparseCompleter):
11311133
pass
11321134

1133-
@with_annotated(subcommand_to="team", ap_completer_type=MyCompleter)
1135+
@with_annotated(subcommand_to="team", completer_class=MyCompleter)
11341136
def team_create(self, name: str) -> None: ...
11351137

11361138
spec = getattr(team_create, constants.SUBCOMMAND_ATTR_SPEC)
1137-
assert spec.parser_source().ap_completer_type is MyCompleter
1139+
assert spec.parser_source().completer_class is MyCompleter
11381140

11391141
def test_customization_via_decorator(self) -> None:
11401142
"""description/epilog/titled Group flow through @with_annotated end-to-end."""

0 commit comments

Comments
 (0)