Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.12.1"
rev: "v0.12.2"
hooks:
- id: ruff-format
args: [--config=pyproject.toml]
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
## 3.0.0 (TBD)

- Breaking Change
- Breaking Changes

- Removed macros

- Enhancements
- Simplified the process to set a custom parser for `cmd2's` built-in commands. See
[custom_parser.py](https://github.com/python-cmd2/cmd2/blob/main/examples/custom_parser.py)
example for more details.

## 2.7.0 (June 30, 2025)

- Enhancements
Expand Down Expand Up @@ -693,7 +699,7 @@
- Added `read_input()` function that is used to read from stdin. Unlike the Python built-in
`input()`, it also has an argument to disable tab completion while input is being entered.
- Added capability to override the argument parser class used by cmd2 built-in commands. See
override_parser.py example for more details.
custom_parser.py example for more details.
- Added `end` argument to `pfeedback()` to be consistent with the other print functions like
`poutput()`.
- Added `apply_style` to `pwarning()`.
Expand Down
42 changes: 24 additions & 18 deletions cmd2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""Import certain things for backwards compatibility."""

import argparse
import contextlib
import importlib.metadata as importlib_metadata
import sys

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

from . import plugin
from .ansi import (
Bg,
Cursor,
Expand All @@ -19,28 +18,29 @@
TextStyle,
style,
)
from .argparse_completer import set_default_ap_completer_type
from .argparse_custom import (
Cmd2ArgumentParser,
Cmd2AttributeWrapper,
CompletionItem,
register_argparse_argument_parameter,
set_default_argument_parser_type,
)

# Check if user has defined a module that sets a custom value for argparse_custom.DEFAULT_ARGUMENT_PARSER.
# Do this before loading cmd2.Cmd class so its commands use the custom parser.
cmd2_parser_module = getattr(argparse, 'cmd2_parser_module', None)
if cmd2_parser_module is not None:
import importlib

importlib.import_module(cmd2_parser_module)

from . import plugin
from .argparse_completer import set_default_ap_completer_type
from .cmd2 import Cmd
from .command_definition import CommandSet, with_default_category
from .constants import COMMAND_NAME, DEFAULT_SHORTCUTS
from .decorators import as_subcommand_to, with_argparser, with_argument_list, with_category
from .command_definition import (
CommandSet,
with_default_category,
)
from .constants import (
COMMAND_NAME,
DEFAULT_SHORTCUTS,
)
from .decorators import (
as_subcommand_to,
with_argparser,
with_argument_list,
with_category,
)
from .exceptions import (
Cmd2ArgparseError,
CommandSetRegistrationError,
Expand All @@ -50,7 +50,12 @@
)
from .parsing import Statement
from .py_bridge import CommandResult
from .utils import CompletionMode, CustomCompletionSettings, Settable, categorize
from .utils import (
CompletionMode,
CustomCompletionSettings,
Settable,
categorize,
)

__all__: list[str] = [ # noqa: RUF022
'COMMAND_NAME',
Expand All @@ -70,8 +75,8 @@
'Cmd2AttributeWrapper',
'CompletionItem',
'register_argparse_argument_parameter',
'set_default_argument_parser_type',
'set_default_ap_completer_type',
'set_default_argument_parser_type',
# Cmd2
'Cmd',
'CommandResult',
Expand All @@ -87,6 +92,7 @@
'Cmd2ArgparseError',
'CommandSetRegistrationError',
'CompletionError',
'PassThroughException',
'SkipPostcommandHooks',
# modules
'plugin',
Expand Down
19 changes: 12 additions & 7 deletions cmd2/argparse_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
parser that inherits from it. This will give a consistent look-and-feel between
the help/error output of built-in cmd2 commands and the app-specific commands.
If you wish to override the parser used by cmd2's built-in commands, see
override_parser.py example.
custom_parser.py example.

Since the new capabilities are added by patching at the argparse API level,
they are available whether or not Cmd2ArgumentParser is used. However, the help
Expand Down Expand Up @@ -1378,15 +1378,20 @@ def set(self, new_val: Any) -> None:
self.__attribute = new_val


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


def set_default_argument_parser_type(parser_type: type[argparse.ArgumentParser]) -> None:
"""Set the default ArgumentParser class for a cmd2 app.
def set_default_argument_parser_type(parser_type: type[Cmd2ArgumentParser]) -> None:
"""Set the default ArgumentParser class for cmd2's built-in commands.

This must be called prior to loading cmd2.py if you want to override the parser for cmd2's built-in commands.
See examples/override_parser.py.
Since built-in commands rely on customizations made in Cmd2ArgumentParser,
your custom parser class should inherit from Cmd2ArgumentParser.

This should be called prior to instantiating your CLI object.

See examples/custom_parser.py.
"""
global DEFAULT_ARGUMENT_PARSER # noqa: PLW0603
DEFAULT_ARGUMENT_PARSER = parser_type
Loading
Loading