NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3179 most downloaded on PyPI
cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
Last release 16 days ago
08 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
19 years old
174 releases · first in 2008
Converted persistent history files from pickle to compressed JSON
Exclude plugins and tests_isolated directories from tarball published to PyPI for cmd2 release
plugins and tests_isolated directories from tarball published to PyPI for cmd2
releaseOne column per quarter.
Removed with_argparser_and_unknown_args since it was deprecated in 1.3.0.
cmd2 2.0 supports Python 3.6+ (removed support for Python 3.5)choices_function / choices_method with choices_provider.completer_function / completer_method with completer.cmd2.Cmd or CommandSet instance as the first
positional argument to choices_provider and completer functions.basic_complete from utils into cmd2.Cmd class.CompletionError to exceptions.pyNamespace.__statement__ has been removed. Use Namespace.cmd2_statement.get() instead.--silent flag from alias/macro create since startup scripts can be run silently.--with_silent flag from alias/macro list since startup scripts can be run
silently.with_argparser_and_unknown_args since it was deprecated in 1.3.0.silent_startup_script to silence_startup_script for clarity.cmd2.Cmd.completion_header with cmd2.Cmd.formatted_completions. See Enhancements
for description of this new class member.cmd2.Cmd.settables is no longer a
public dict attribute - it is now a property that aggregates all Settables across all
registered CommandSets.use_ipython keyword parameter of cmd2.Cmd.__init__() to include_ipy.py command is only enabled if include_py parameter is True. See Enhancements for a
description of this parameter.py. Now py takes no
arguments and just opens an interactive Python shell.runcmds_plus_hooks() to not stop when Ctrl-C is pressed and
instead run the next command in its list.cmd2.Cmd.quit_on_sigint flag, which when True, quit the application when Ctrl-C
was pressed at the prompt.cmd2.history. Therefore,
persistent history files created with versions older than 2.0.0 are not compatible.cmd2.Cmd2.read_input.
See read_input.py for
an example.cmd2.exceptions.PassThroughException to raise unhandled command exceptions instead of
printing them.cmd2.Cmd.formatted_completions. cmd2 provides this capability automatically if you return
argparse completion matches as CompletionItems.SystemExit or calling sys.exit() in a command or hook function will set
self.exit_code to the exit code used in those calls. It will also result in the command loop
stopping.self.py_locals in the IPython environmentinclude_py keyword parameter to cmd2.Cmd.__init__(). If False, then the py
command will not be available. Defaults to False. run_pyscript is not affected by this
parameter.cmd2.Cmd._run_editor() to the public method cmd2.Cmd.run_editor()Fixed bug where setting always_show_hint=True did not show a hint when completing Settables
always_show_hint=True did not show a hint when completing
SettableswhichFileNotFoundError which occurred when running history --clear and no history file
existed.silent_startup_script option to cmd2.Cmd.__init__(). If True, then the startup
script's output will be suppressed. Anything written to stderr will still display.Fixed tab completion crash on Windows
Fixed issue where quoted redirectors and terminators in aliases and macros were not being restored when read from a startup script.
@as_subcommand_to decorator resulted in duplicated help text in the base command the
subcommands belong to.Added user-settable option called always_show_hint. If True, then tab completion hints will always display even when tab completion suggestions print.
always_show_hint. If True, then tab completion hints will
always display even when tab completion suggestions print. Arguments whose help or hint text
is suppressed will not display hints even when this setting is True.--silent flag to alias/macro create. If used, then no confirmation message will be
printed when aliases and macros are created or overwritten.--with_silent flag to alias/macro list. Use this option when saving to a startup
script that should silently create aliases and macros.CommandSet.on_unregister() is now called as first step in unregistering a CommandSet and not the last. CommandSet.on_unregistered() is now the last st
CommandSet.on_unregister() is now called as first step in unregistering a CommandSet and
not the last. CommandSet.on_unregistered() is now the last step.CommandSet.on_registered(). This is called by cmd2.Cmd after a CommandSet is
registered and all its commands have been added to the CLI.CommandSet.on_unregistered(). This is called by cmd2.Cmd after a CommandSet is
unregistered and all its commands have been removed from the CLI.Fixed issue where subcommand added with @as_subcommand_to decorator did not display help when called with -h/--help.
@as_subcommand_to decorator did not display help
when called with -h/--help.add_help=False no longer has to be passed to parsers used in @as_subcommand_to decorator.
Only pass this if your subcommand should not have the -h/--help help option (as stated in
argparse documentation).Fixes an issue introduced in 1.3.0 with processing command strings containing terminator/separator character(s) that are manually passed to a command
The functions cmd2 adds to Namespaces (get_statement() and get_handler()) are now Cmd2AttributeWrapper objects named cmd2_statement and cmd2_handler.
get_statement() and get_handler()) are now
Cmd2AttributeWrapper objects named cmd2_statement and cmd2_handler. This makes it easy
to filter out which attributes in an argparse.Namespace were added by cmd2.Namespace.__statement__ will be removed in cmd2 2.0.0. Use
Namespace.cmd2_statement.get() going forward.Fixed RecursionError when printing an argparse.Namespace caused by custom attribute cmd2 was adding
RecursionError when printing an argparse.Namespace caused by custom attribute cmd2
was addingget_statement() function to argparse.Namespace which returns __statement__
attributeFixed AttributeError when CommandSet that uses as_subcommand_to decorator is loaded during cmd2.Cmd.__init__().
AttributeError when CommandSet that uses as_subcommand_to decorator is loaded
during cmd2.Cmd.__init__().spec=True. See
testing documentation for more details
on testing cmd2-based applications with mock.CommandSet command functions (do*, complete*, help\_) will no longer have the cmd2 app passed in as the first parameter after self since this is alrea
self since this is already a class member.install_command_set() and uninstall_command_set() to register_command_set() and
unregister_command_set() for better name consistency.Cmd2ArgumentParser when metavar is a tupleCompletionItem on an argument whose metavar is a tupleFixed prog value of subcommands added with as_subcommand_to() decorator.
prog value of subcommands added with as_subcommand_to() decorator.as_subcommand_to() decorator.
These settings include things like description and epilog text.Fixed issue determining whether an argparse completer function required a reference to a containing CommandSet. Also resolves issues determining the c
cmd2.Cmd.path_complete as a completer for an argparse-based command defined in a CommandSetMarked with_argparser_and_unknown_args pending deprecation and consolidated implementation into with_argparser
Relax minimum version of importlib-metadata to >= 1.6.0 when using Python < 3.8
importlib-metadata to >= 1.6.0 when using Python < 3.8Fixed typing module compatibility issue with Python 3.5 prior to 3.5.4
typing module compatibility issue with Python 3.5 prior to 3.5.4importlib.metadata instead of using pkg_resources
cmd2 application launch time on systems that have a lot of Python packages on
sys.pathimportlib_metadata when running on versions of Python prior to 3.8Fixed issue where subcommand usage text could contain a subcommand alias instead of the actual name
ArgparseCompleter where fill_width could become negative if token_width was
large relative to the terminal width.ipy consistent with py in the following ways
ipy returns whether any of the commands run in it returned True to stop command loopCmd.in_pyscript() returns True while in ipy.ipy when Cmd.in_pyscript() is already True is not allowed.with_argument_list, with_argparser, and with_argparser_and_unknown_args wrappers now
pass kwargs through to their wrapped command function.table_creator module for creating richly formatted tables. This module is in beta and
subject to change.
SkipPostcommandHooks - Custom exception class for when a command has a failure bad
enough to skip post command hooks, but not bad enough to print the exception to the user.Cmd2ArgparseError - A SkipPostcommandHooks exception for when a command fails to parse
its arguments. Normally argparse raises a SystemExit exception in these cases. To avoid
stopping the command loop, catch the SystemExit and raise this instead. If you still
need to run post command hooks after parsing fails, just return instead of raising an
exception.SystemExit. If a command raises this exception, the command loop
will be gracefully stopped.Ctrl-C now stops a running text script instead of just the current run_script command
run_script commanddo_shell() now saves the return code of the command it runs in self.last_result for use in
pyscriptsFixed issue where postcmd hooks were running after an argparse exception in a command.
argparse exception in a command.The documentation at cmd2.rftd.io received a major overhaul
cmd2 intends to follow
Semantic VersioningWe intend no more breaking changes prior to 1.0.0
utils.truncate_line().cmd2.Cmd.py_locals dictionary.sys.path[0] for a pyscript to cmd2's working directory instead of
the script file's directory.sys.path was not being restored after a pyscript ran.-l/--long flag to -v/--verbose for consistency with help and history
commands.__name__: main__file__: script path (as typed, ~ will be expanded)CompletionError exception available to non-argparse tab completionapply_style to CompletionError initializer. It defaults to True, but can be set to
False if you don't want the error text to have ansi.style_error() applied to it when
printed.py run command since it was replaced by run_pyscript a while agoAutoCompleter to ArgparseCompleter for clarityEmptyStatement exception is no longer part of the documented public APIWe intend no more breaking changes prior to 1.0.0
help -v more discoverableadd_settable() and remove_settable() convenience methods to update self.settable
dictionaryansi.fg and ansi.bg enums of foreground and background colors
ansi.style() fg argument can now either be of type str or ansi.fgansi.style() bg argument can now either be of type str or ansi.bgf-strings and format() calls (e.g. "{}hello{}".format(fg.blue, fg.reset))fg.blue + "hello" + fg.reset)locals_in_py attribute of cmd2.Cmd to self_in_pycmd2.Cmd are no longer settable at runtime by default:
continuation_promptself_in_pypromptself.settable changed to self.settables
cast() utility functionansi.FG_COLORS and ansi.BG_COLORS dictionaries
ansi.fg and ansi.bg enums providing similar but improved functionalityReduced what gets put in package downloadable from PyPI (removed irrelevant CI config files and such)
Flushing stderr when setting the window title and printing alerts for better responsiveness in cases where stderr is not unbuffered.
cmd2.utils.truncate_line supports characters with display widths greater than 1 and ANSI
style sequences.cmd2.utils text alignment functions.Fixed bug where startup script containing a single quote in its file name was incorrectly quoted
setuptools due to build with setuptools_scmstyle() function and ansi.INTENSITY_DIM setting.ansi members for accuracy in what types of ANSI escape sequences are
handled
ansi.allow_ansi -> ansi.allow_styleansi.ansi_safe_wcswidth() -> ansi.style_aware_wcswidth()ansi.ansi_aware_write() -> ansi.style_aware_write()ansi members for clarification
ansi.BRIGHT -> ansi.INTENSITY_BRIGHTansi.NORMAL -> ansi.INTENSITY_NORMALFixed bug where a redefined ansi.style_error was not being used in all cmd2 files
ansi.style_error was not being used in all cmd2 filesalign_left(), align_center(), and align_right() to utils.py. All 3 of these
functions support ANSI escape sequences and characters with display widths greater than 1.
They wrap align_text() which is also in utils.py.Fixed bug where pipe processes were not being stopped by Ctrl-C
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.end argument to pfeedback() to be consistent with the other print functions like
poutput().apply_style to pwarning().end and chop keyword-only arguments of ppaged()end is always added to message in ppaged()Fixed bug where setting use_ipython to False removed ipy command from the entire cmd2.Cmd class instead of just the instance being created
use_ipython to False removed ipy command from the entire cmd2.Cmd
class instead of just the instance being creatededit command by having do_history no longer call
do_edit. This also removes the need to exclude edit command from history list.prog attribute of an argparser with subcommands. cmd2
now automatically sets the prog value of it and all its subparsers so that all usage
statements contain the top level command name and not sys.argv[0].Fixed ValueError exception which could occur when an old format persistent history file is loaded with new cmd2
ValueError exception which could occur when an old format persistent history file is
loaded with new cmd2Fixed bug introduced in 0.9.17 where help functions for hidden and disabled commands were not being filtered out as help topics
AutoCompleter now handles argparse's mutually exclusive groups. It will not tab complete
flag names or positionals for already completed groups. It also will print an error if you try
tab completing a flag's value if the flag belongs to a completed group.AutoCompleter now uses the passed-in parser's help formatter to generate hint text. This
gives help and hint text for an argument consistent formatting.Fixed a bug when using WSL when all Windows paths have been removed from $PATH
cmd2.Cmd object instance with a do_xxx method at runtimearg_tokens, then
AutoCompleter will automatically pass this dictionary to them.Cmd.in_script() - return whether a text script is runningCmd.in_pyscript() - return whether a pyscript is runningFixed inconsistent parsing/tab completion behavior based on the value of allow_redirection. This flag is only meant to be a security setting that prev
allow_redirection.
This flag is only meant to be a security setting that prevents redirection of stdout and
should not alter parsing logic.TypeError if trying to set choices/completions on argparse action that accepts no
argumentsset_choices_function(), set_choices_method(), set_completer_function(), and
set_completer_method() to support cases where this functionality needs to be added to an
argparse action outside of the normal parser.add_argument() call.Fixed exception caused by tab completing after an invalid subcommand was entered
history -v was sometimes showing raw and expanded commands when they weren't
differentload - replaced by run_script_relative_load - replaced by _relative_run_scriptpyscript - replaced by run_pyscriptload should be loadingcmd2.Cmd.statement_parser to be a public attribute (no underscore)
ACArgumentParser is now called Cmd2ArgumentParserbasic_complete to utils.pydelimiter_complete,
flag_based_complete, index_based_complete, path_complete, shell_cmd_complete--output-file to --output_filematches_sort_key to default_sort_key. This value determines the default sort
ordering of string results like alias, command, category, macro, settable, and shortcut names.
Unsorted tab completion results also are sorted with this key. Its default value
(ALPHABETICAL_SORT_KEY) performs a case-insensitive alphabetical sort, but it can be changed
to a natural sort by setting the value to NATURAL_SORT_KEY.StatementParser now expects shortcuts to be passed in as dictionary. This eliminates the
step of converting the shortcuts dictionary into a tuple before creating StatementParser.Cmd.pyscript_name to Cmd.py_bridge_nameCmd.pystate to Cmd.py_localsPyscriptBridge to PyBridgeAdded support for and testing with Python 3.8, starting with 3.8 beta
ansi module with functions and constants to support ANSI escape sequences which are
used for things like applying style to textstyle() function in
ansi modulesuccess, warning. and error text. These are
the styles used by cmd2 and can be overridden to match the color scheme of your application.ansi_aware_write() function to ansi module. This function takes into account the
value of allow_ansi to determine if ANSI escape sequences should be stripped when not
writing to a tty. See documentation for more information on the allow_ansi setting.cmd2
cmd2 0.9.13cmd2.Cmd class
perror into 2 functions:
perror - print a message to sys.stderrpexcept - print Exception message to sys.stderr. If debug is true, print exception
traceback if one existspoutput and perror significantly changed
color, err_color, and war_color from poutput and perror
end argument is now keyword-only and cannot be specified positionallytraceback_war no longer exists as an argument since it isn't needed now that perror
and pexcept existcmd2.Cmd.colors to ansi.py and renamed it to allow_ansi. This is now an
application-wide setting.COLORS_ALWAYS --> ANSI_ALWAYSCOLORS_NEVER --> ANSI_NEVERCOLORS_TERMINAL --> ANSI_TERMINALload --> run_script_relative_load --> _relative_run_scriptpyscript --> run_pyscriptFixed issue where the wrong terminator was being appended by Statement.expanded_command_line()
Statement.expanded_command_line()expanded or verbose arguments to
history to see the resolved value for the macro.Statement.expanded_command_line()_cmdloop() suppressed exceptions by returning from within its finally
codepyscript limits a command's stdout capture to the same period that redirection does.
Therefore output from a command's postparsing and finalization hooks isn't saved in the StdSim
object.StdSim.buffer.write() now flushes when the wrapped stream uses line buffering and the bytes
being written contain a newline or carriage return. This helps when pyscript is echoing the
output of a shell command since the output will print at the same frequency as when the
command is run in a terminal.ns_provider argument for more information.exit_code returned from cmdloop based on Success/Failurecmd2 based apps now shows in the history
command.cmdqueue. This allows
easy capture of the entire script's output.CommandResult called stop which is the return value of onecmd_plus_hooks
after it runs the given command line.unquote_redirection_tokens() with unquote_specific_tokens(). This was to support
the fix that allows terminators in alias and macro values.Statement.pipe_to to a string instead of a listpreserve_quotes is now a keyword-only argument in the argparse decoratorscmd2.Cmd.cmdloop() returns the exit_code instead of a call to
sys.exit() It is now application developer's responsibility to treat the return value from
cmdloop() accordinglycmd2 based apps.
Previously all user input was persistent in history. If readline is installed, the history
available with the up and down arrow keys (readline history) may not match that shown in the
history command, because history only tracks valid input, while readline history captures
all input.cmd2 based app of version 0.9.13 or higher.str. If you are directly accessing the
.history attribute of a cmd2 based app, you will need to update your code to use
.history.get(1).statement.raw instead.eos command that was used to keep track of when a text script's
commands endedcmd2 member called _STOP_AND_EXIT since it was just a boolean value that should
always be Truecmd2 member called _should_quit since PyBridge now handles this logiccmd.cmdqueueallow_cli_args is now an argument to init instead of a cmd2 class membercmd2 which will support Python 3.4Fixed a bug in how redirection and piping worked inside py or pyscript commands
py or pyscript commandsasync_alert where it didn't account for prompts that contained newline
charactersdisable_command() or disable_category() for more details.help_error - the error that prints when no help
information can be found _ default_error - the error that prints when a non-existent command
is runwith_argparser decorators now add the Statement object created when parsing the command
line to the argparse.Namespace object they pass to the do_* methods. It is stored in an
attribute called __statement__. This can be useful if a command function needs to know the
command line for things like logging.-t option to the load command for automatically generating a transcript based on a
script fileCommandResult structure.do_help() - when no help information can be found
_ default() - in all cases since this is called when an invalid command name is run *
_report_disabled_command_usage() - in all cases since this is called when a disabled command
is rundo_help() and default()cmd.Cmd class so that all class attributes got converted to
instance attributes, also:
allow_redirection, terminators, multiline_commands, and shortcuts as
optional arguments to cmd2.Cmd.__init__()StatementParser and properties were created
for accessing themself.pipe_proc is now called self.cur_pipe_proc_reader and is a ProcReader class.reserved_words class attribute due to lack of usekeywords instance attribute due to lack of useFixed bug in how history command deals with multiline commands when output to a script
with_argument_list decorator is called with the optional
preserve_quotes argumentperror() where it would try to print an exception Traceback even if none existedmatches_sort_key to override the default way tab completion matches are sortedStdSim.pause_storage member which when True will cause StdSim to not save the output
sent to it. See documentation for CommandResult in pyscript_bridge.py for reasons pausing
the storage can be useful.enable_command()enable_category()disable_command()disable_category()cmd2_app a positional and required argument of AutoCompleter since certain
functionality now requires that it can't be None.AutoCompleter no longer assumes CompletionItem results are sorted. Therefore you should
follow the cmd2 convention of setting self.matches_sorted to True before returning the
results if you have already sorted the CompletionItem list. Otherwise it will be sorted
using self.matches_sort_key.AutoCompleter which has since developed a dependency on cmd2 methods.pyscript as if they were functions (e.g. app.help())
in favor of only supporting one pyscript interface. This simplifies future maintenance.Fixed unit test that hangs on Windows
Fixed bug where the set command was not tab completing from the current settable dictionary.
set command was not tab completing from the current settable
dictionary.Fixed issue with echoing strings in StdSim. Because they were being sent to a binary buffer, line buffering was being ignored.
Deletions (potentially breaking changes)
Cmd.select()cmd_echo always starts as False in a py script. This was broken in
0.9.5.default_to_shell being True now run via do_shell() and are
saved to history.Cmd.colorize() and Cmd._colorcodes which were deprecated in 0.9.5dir_exe_only and dir_only flags in path_complete with optional path_filter
function that is used to filter paths out of completion results.perror() no longer prepends "ERROR: " to the error message being printedFixed bug introduced in 0.9.5 caused by backing up and restoring self.prompt in pseudo_raw_input. As part of this fix, continuation prompts will not b
self.prompt in
pseudo_raw_input. As part of this fix, continuation prompts will not be redrawn with
async_update_prompt or async_alert.py now go through onecmd_plus_hooks.Deletions (potentially breaking changes)
get_all_commands could return non-callable attributesexit_code attribute of cmd2.Cmd class
cmdloopACHelpFormatter now inherits from argparse.RawTextHelpFormatter to make it easier for
formatting help/description textasync_alert, async_update_prompt, and set_window_title functions
colorama gets initialized properly in Cmd.__init()Cmd.colors setting is no longer platform dependent and now has three values:
macro command to create macros, which are similar to aliases, but can take arguments
when calledcmd2 support for colors including Cmd.colorize() and
Cmd._colorcodespreparse, postparsing_precmd, and postparsing_postcmd methods deprecated in the
previous release have been deleted * The new application lifecycle hook system allows for
registration of callbacks to be called at various points in the lifecycle and is more powerful
and flexible than the previous systemalias is now a command with subcommands to create, list, and delete aliases. Therefore its
syntax has changed. All current alias commands in startup scripts or transcripts will break
with this release.unalias was deleted since alias delete replaced itDeprecated the following hook methods, see hooks.rst for full details:
preparse was not getting calleddocs/hooks.rst
for details.attrs third party modulematches_sorted member to support custom sorting of tab completion matcheshooks.rst for full details:
cmd2.Cmd.preparse() - equivalent functionality available via
cmd2.Cmd.register_postparsing_hook()cmd2.Cmd.postparsing_precmd() - equivalent functionality available via
cmd2.Cmd.register_postparsing_hook()cmd2.Cmd.postparsing_postcmd() - equivalent functionality available via
cmd2.Cmd.register_postcmd_hook()The CmdResult helper class which was _deprecated_ in the previous release has now been deleted
__init__() was called with terminators equal to NoneCmd.onecmd() was called with a raw str--clear flag to history command that clears both the command and readline history.CmdResult helper class which was deprecated in the previous release has now been
deleted
CommandResult classThe CmdResult helper class is _deprecated_ and replaced by the improved CommandResult class
completion_header
memberpager and pager_chop attributes to the cmd2.Cmd class
pager defaults to less -RXF on POSIX and more on Windowspager_chop defaults to less -SRXF on POSIX and more on Windowschop argument to cmd2.Cmd.ppaged() method for displaying output using a pager
chop is False, then self.pager is used as the pagerself.pager_chop is used as the pagertabulateCmdResult helper class is deprecated and replaced by the improved CommandResult
class
CommandResult has the following attributes: stdout, stderr, and data
CmdResult had attributes of: out, err, warCmdResult will be deleted in the next releasefix packaging error for 0.8.x versions (yes we had to deploy a new version of the 0.9.x series to fix a packaging error with the 0.8.x version)
Nothing published for this version
Fixed extra slash that could print when tab completing users on Windows
Prevent crashes that could occur attempting to open a file in non-existent directory or with very long filename
display_matches is no longer restricted to delimited stringsNothing published for this version
Nothing published for this version
Nothing published for this version
Commands using the @with_argparser_and_unknown_args were not correctly recognized when tab completing
AttributeError on Windows when running a select command cause by pyreadline not
implementing remove_history_itempy console in the following ways
py console history from the cmd2 historyFixed a bug with all argument decorators where the wrapped function wasn't returning a value and thus couldn't cause the cmd2 app to quit
Bug Fixes
Enhancements
ctypesdisplay_matches list to clarify its purpose. See cmd2.py for this
documentation.Python 2 EOL notice
cmd2 for Python 2.7cmd2 will support Python 3.4+ onlyFixed conditional dependency issue in setup.py that was in 0.8.3.
Fixed help command not calling functions for help topics
Bug Fixes
help command not calling functions for help topics< and >Enhancements
delimiter_complete function for tab completing delimited stringsallow_appended_spaceallow_closing_quoteAttribute Changes (Breaks backward compatibility)
exclude_from_help is now called hidden_commands since these commands are hidden from
things other than help, including tab completion
do_history), but instead
uses the command names themselves (history)excludeFromHistory is now called exclude_from_historycmd_with_subs_completer() no longer takes an argument called base. Adding tab completion
to subcommands has been simplified to declaring it in the subcommand parser's default
settings. This easily allows arbitrary completers like path_complete to be used. See
subcommands.py for an
example of how to use tab completion in subcommands. In addition, the docstring for
cmd_with_subs_completer() offers more details.Your coding agent can read these notes before it upgrades. Set up the MCP server →