Skip to content

Parser building functions. #1458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2025
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