Skip to content

Commit 43df863

Browse files
committed
All built-in commands now use a function to create their argument parser.
This simplifies the process for overriding cmd2's default parser class.
1 parent acb824b commit 43df863

File tree

11 files changed

+366
-304
lines changed

11 files changed

+366
-304
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
## 3.0.0 (TBD)
22

3-
- Breaking Change
3+
- Breaking Changes
4+
45
- Removed macros
56

7+
- Enhancements
8+
- Simplified the process to set a custom parser for `cmd2's` built-in commands. See
9+
[custom_parser.py](https://github.com/python-cmd2/cmd2/blob/main/examples/custom_parser.py)
10+
example for more details.
11+
612
## 2.7.0 (June 30, 2025)
713

814
- Enhancements

cmd2/__init__.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""Import certain things for backwards compatibility."""
22

3-
import argparse
43
import contextlib
54
import importlib.metadata as importlib_metadata
6-
import sys
75

86
with contextlib.suppress(importlib_metadata.PackageNotFoundError):
97
__version__ = importlib_metadata.version(__name__)
108

9+
from . import plugin
1110
from .ansi import (
1211
Bg,
1312
Cursor,
@@ -19,28 +18,29 @@
1918
TextStyle,
2019
style,
2120
)
21+
from .argparse_completer import set_default_ap_completer_type
2222
from .argparse_custom import (
2323
Cmd2ArgumentParser,
2424
Cmd2AttributeWrapper,
2525
CompletionItem,
2626
register_argparse_argument_parameter,
2727
set_default_argument_parser_type,
2828
)
29-
30-
# Check if user has defined a module that sets a custom value for argparse_custom.DEFAULT_ARGUMENT_PARSER.
31-
# Do this before loading cmd2.Cmd class so its commands use the custom parser.
32-
cmd2_parser_module = getattr(argparse, 'cmd2_parser_module', None)
33-
if cmd2_parser_module is not None:
34-
import importlib
35-
36-
importlib.import_module(cmd2_parser_module)
37-
38-
from . import plugin
39-
from .argparse_completer import set_default_ap_completer_type
4029
from .cmd2 import Cmd
41-
from .command_definition import CommandSet, with_default_category
42-
from .constants import COMMAND_NAME, DEFAULT_SHORTCUTS
43-
from .decorators import as_subcommand_to, with_argparser, with_argument_list, with_category
30+
from .command_definition import (
31+
CommandSet,
32+
with_default_category,
33+
)
34+
from .constants import (
35+
COMMAND_NAME,
36+
DEFAULT_SHORTCUTS,
37+
)
38+
from .decorators import (
39+
as_subcommand_to,
40+
with_argparser,
41+
with_argument_list,
42+
with_category,
43+
)
4444
from .exceptions import (
4545
Cmd2ArgparseError,
4646
CommandSetRegistrationError,
@@ -50,7 +50,12 @@
5050
)
5151
from .parsing import Statement
5252
from .py_bridge import CommandResult
53-
from .utils import CompletionMode, CustomCompletionSettings, Settable, categorize
53+
from .utils import (
54+
CompletionMode,
55+
CustomCompletionSettings,
56+
Settable,
57+
categorize,
58+
)
5459

5560
__all__: list[str] = [ # noqa: RUF022
5661
'COMMAND_NAME',
@@ -70,8 +75,8 @@
7075
'Cmd2AttributeWrapper',
7176
'CompletionItem',
7277
'register_argparse_argument_parameter',
73-
'set_default_argument_parser_type',
7478
'set_default_ap_completer_type',
79+
'set_default_argument_parser_type',
7580
# Cmd2
7681
'Cmd',
7782
'CommandResult',
@@ -87,6 +92,7 @@
8792
'Cmd2ArgparseError',
8893
'CommandSetRegistrationError',
8994
'CompletionError',
95+
'PassThroughException',
9096
'SkipPostcommandHooks',
9197
# modules
9298
'plugin',

cmd2/argparse_custom.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,15 +1378,20 @@ def set(self, new_val: Any) -> None:
13781378
self.__attribute = new_val
13791379

13801380

1381-
# The default ArgumentParser class for a cmd2 app
1382-
DEFAULT_ARGUMENT_PARSER: type[argparse.ArgumentParser] = Cmd2ArgumentParser
1381+
# Parser type used by cmd2's built-in commands.
1382+
# Set it using cmd2.set_default_argument_parser_type().
1383+
DEFAULT_ARGUMENT_PARSER: type[Cmd2ArgumentParser] = Cmd2ArgumentParser
13831384

13841385

1385-
def set_default_argument_parser_type(parser_type: type[argparse.ArgumentParser]) -> None:
1386-
"""Set the default ArgumentParser class for a cmd2 app.
1386+
def set_default_argument_parser_type(parser_type: type[Cmd2ArgumentParser]) -> None:
1387+
"""Set the default ArgumentParser class for cmd2's built-in commands.
13871388
1388-
This must be called prior to loading cmd2.py if you want to override the parser for cmd2's built-in commands.
1389-
See examples/override_parser.py.
1389+
Since built-in commands rely on customizations made in Cmd2ArgumentParser,
1390+
your custom parser class should inherit from Cmd2ArgumentParser.
1391+
1392+
This should be called prior to instantiating your CLI object.
1393+
1394+
See examples/custom_parser.py.
13901395
"""
13911396
global DEFAULT_ARGUMENT_PARSER # noqa: PLW0603
13921397
DEFAULT_ARGUMENT_PARSER = parser_type

0 commit comments

Comments
 (0)