4.0.0 (June 5, 2026) #1676
Replies: 1 comment
-
|
One interesting side effect of the change to using This may result in some surprising behavior for a small percentage of users. In particular, this is likely to impact anyone using Python's built-in |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
cmd2now has a dependency on prompt-toolkit which serves as a pure-Python cross-platform replacement for GNU Readline. Previously,cmd2had used differentreadlinedependencies on each Operating System (OS) which was at times a very frustrating developer and user experience due to small inconsistencies in these different readline libraries. Now we have consistent cross-platform support for tab-completion, user terminal input, and history. Additionally, this opens up some cool advanced features such as support for syntax highlighting of user input while typing, auto-suggestions similar to those provided by the fish shell, and the option for a persistent bottom bar that can display realtime status updates while the prompt is displayed.Details
readlinebuilt-in module and underlying platform librariescmd2.rl_utilsmodule which dealt with importing the properreadlinemodule for each platform and provided utility functions related toreadlineprompt-toolkitand a newcmd2.pt_utilsmodule with supporting utilitiescmd2now requires Python 3.11 or laterhistory -toption for generating transcript files and thecmd2.transcriptmoduleprompt-toolkitstarts its ownasyncioevent loop in everycmd2applicationcmd2.Cmd.terminal_lockas it is no longer required to support things likecmd2.Cmd.async_alertcmd2.Cmd.async_refresh_promptandcmd2.Cmd.need_prompt_refreshas they are no longer neededcompleterfunctions must now return acmd2.Completionsobject instead oflist[str].choices_providerfunctions must now return acmd2.Choicesobject instead oflist[str].descriptive_headersfield is now calledtable_columns.CompletionItem.descriptive_datais now calledCompletionItem.table_data.DEFAULT_DESCRIPTIVE_HEADERS. This means you must definetable_columnswhen usingCompletionItem.table_datadata.Cmd.default_sort_keymoved toutils.DEFAULT_STR_SORT_KEY.Cmd, into other classes.Cmd.matches_sorted->Completions.is_sortedandChoices.is_sortedCmd.completion_hint->Completions.hintCmd.formatted_completions->Completions.table(Now a Rich Table)Cmd.allow_appended_space/allow_closing_quote->Completions.allow_finalizationCmd.matches_delimitedsince it's no longer used.flag_based_completeandindex_based_completefunctions since their functionality is already provided in arpgarse-based completion.Statement.multiline_commandfrom a string to a bool.Statement.arg_lista property which generates the list on-demand.Statement.outputtoStatement.redirector.Statement.output_totoStatement.redirect_to.Statement.pipe_tosince it can be handled byStatement.redirectorandStatement.redirect_to.StatementParser.parse_command_only()to return aPartialStatementobject.Macro.arg_listtoMacro.args.terminal_utils.pysinceprompt-toolkitprovides this functionality.async_alert()andasync_update_prompt()with a single function calledadd_alert(). This new function is thread-safe and does not require you to acquire a mutex before calling it like the previous functions did.Cmd.default_to_shell.Cmd.rulersincecmd2no longer uses it.cmd2commands must be an instance ofCmd2ArgumentParseror a child class of it.set_default_argument_parser_type()toset_default_argument_parser().set_default_ap_completer_type()toset_default_argparse_completer().set_ap_completer_type()andget_ap_completer_type()sincecompleter_classis now a public member ofCmd2ArgumentParser.set_parser_prog()toCmd2ArgumentParser.update_prog().cmd2_handlertocmd2_subcommand_funcin theargparse.Namespacefor clarity.Cmd2AttributeWrapperclass.argparse.Namespaceobjects passed to command functions now contain direct attributes forcmd2_statementandcmd2_subcommand_func.cmd2/command_definition.pytocmd2/command_set.py.Cmd.doc_headerand thewith_default_categorydecorator. Help categorization is now driven by theDEFAULT_CATEGORYclass variable (see Simplified command categorization in the Enhancements section below for details).Cmd.undoc_headersince all commands are now considered categorized.Cmd.cmd_func()toCmd.get_command_func().cmd2no longer sets a default title for a subparsers group. If you desire a title, you will need to pass one in like thisparser.add_subparsers(title="subcommands"). This is standardargparsebehavior.TextGroupnow implementsHelpFormatterRenderable(see Enhancements section below for more details).formatter_creatorparameter fromTextGroup.__init__().Cmd2ArgumentParser.create_text_group()method.argparseandRichintegration refactoring:argparse_custommodule toargparse_utils.argparse_utilstorich_utils:Cmd2HelpFormatterArgumentDefaultsCmd2HelpFormatterMetavarTypeCmd2HelpFormatterRawDescriptionCmd2HelpFormatterRawTextCmd2HelpFormatterTextGroupAPP_THEMEconstant inrich_utils.pywithget_theme(),reset_theme(), andupdate_theme()functions intheme.pyto support lazy initialization and safer in-place updates of the theme.Cmd._command_parserstoCmd.command_parsers.RichPrintKwargsTypedDictin favor of usingMapping[str, Any], allowing for greater flexibility in passing keyword arguments toconsole.print()calls.always_show_hintsettable as it provided a poor user experience withprompt-toolkitcmd2redirection only captures output directed toself.stdout(e.g., viaself.poutput()). Standardprint()calls write directly tosys.stdoutand are not captured. However,print()calls withinpyscriptsand the interactive Python shell are treated as command output and sent toself.stdout, allowing them to be captured.feedback_to_outputsettable and changedcmd2.Cmd.pfeedbackto always print toself.stdoutCmd.parseline()since it was unused and merely wrappedStatementParser.parse_command_only().cmd2.CmdparametersTrue, provide fish shell style auto-suggestions. These are grayed-out hints based on history. User can press right-arrow key to accept the provided suggestion.True, present a persistent bottom toolbar capable of displaying realtime status information while the prompt is displayed, see thecmd2.Cmd2.get_bottom_toolbarmethod that can be overridden as well as the updatedgetting_started.pyexamplecmd2.Cmdmethodsbottom_toolbarisTrueprompt-toolkitevent loop has startedrich.pretty.pprint()cmd2.Cmd.selecthas been revamped to use the choice function fromprompt-toolkitwhen both stdin and stdout are TTYsargparsechangescommon_prefixmethod tocmd2.string_utilsmodule as a replacement foros.path.commonprefixsince that is now deprecated in Python 3.15DEFAULT_CATEGORY.with_category()decorator.examples/default_categories.pyfile.CommandSetis now a generic class, which allows developers to parameterize it with their specificcmd2.Cmdsubclass (e.g.,class MyCommandSet(CommandSet[MyApp]):). This provides full type hints and IDE autocompletion forself._cmdwithout needing to override and cast the property.traceback_kwargsattribute to allow customization of Rich-based tracebacks.HelpFormatterRenderableprotocol andHelpContenttype alias to support context-aware help content inargparse.print()function available in apyscriptwrites toself.stdoutand respects theallow_stylesetting. It also supports printingRichobjects.Cmd2ArgumentParser.output_to()context manager to temporarily set the output stream duringargparseoperations. This is helpful for directing output for functions likeparse_args(), which default tosys.stdoutand lack afileargument.prompt-toolkitcompletion menu colors by overriding the following fields in thecmd2theme:Cmd2Style.COMPLETION_MENU- Base style for the entire completion menu container (sets the background)Cmd2Style.COMPLETION_MENU_COMPLETION-Style for an individual, non-selected completion itemCmd2Style.COMPLETION_MENU_CURRENT- Style for the currently selected completion itemCmd2Style.COMPLETION_MENU_META- Style for "meta" information shown alongside a completionCmd2Style.COMPLETION_MENU_META_CURRENT- Style for meta info of current itemsetcommand to consolidate its confirmation output into a single, colorized line. The confirmation now usespfeedback(), allowing it to be silenced when thequietsettable is enabled.aliasandmacrosubcommands forcreateanddeletenow output their non-essential success case output usingpfeedback@with_annotateddecorator, a type-hint-driven alternative to@with_argparsethat builds the parser automatically from a command's signature (positional/option inference, enum/literal/path/collection handling, subcommands, groups, mutex). See the annotated_example.py example for demonstration of usage.cmd2command parameters using type hints using syntax essentially identical to that used by Typer@with_annotateddecorator builds anargparseparser for youThis discussion was created from the release 4.0.0 (June 5, 2026).
Beta Was this translation helpful? Give feedback.
All reactions