diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0510bb303..0314693cc 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -14,7 +14,7 @@ repos:
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: "v0.16.4"
+ rev: "v0.16.5"
hooks:
- id: ruff-format
args: [--config=ruff.toml]
@@ -30,7 +30,7 @@ repos:
- prettier-plugin-toml@2.0.6
- repo: https://github.com/crate-ci/typos
- rev: v1.49.1
+ rev: v1.50.0
hooks:
- id: typos
exclude: |
diff --git a/README.md b/README.md
index 18b569969..780d41b2e 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,7 @@ examples.
```python
#!/usr/bin/env python
"""A simple cmd2 application."""
+
import cmd2
@@ -128,15 +129,14 @@ class FirstApp(cmd2.Cmd):
"""A simple cmd2 application."""
def do_hello_world(self, _: cmd2.Statement):
- self.poutput('Hello World')
+ self.poutput("Hello World")
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
c = FirstApp()
sys.exit(c.cmdloop())
-
```
## Found a bug?
diff --git a/docs/examples/alternate_event_loops.md b/docs/examples/alternate_event_loops.md
index 0dbe1f01d..7fdc3b66e 100644
--- a/docs/examples/alternate_event_loops.md
+++ b/docs/examples/alternate_event_loops.md
@@ -36,13 +36,15 @@ by using code like the following:
```py
import cmd2
+
class Cmd2EventBased(cmd2.Cmd):
def __init__(self):
cmd2.Cmd.__init__(self)
# ... your class code here ...
-if __name__ == '__main__':
+
+if __name__ == "__main__":
app = Cmd2EventBased()
app.preloop()
diff --git a/docs/examples/getting_started.md b/docs/examples/getting_started.md
index 070158891..3c4c14163 100644
--- a/docs/examples/getting_started.md
+++ b/docs/examples/getting_started.md
@@ -19,9 +19,11 @@ click the **Copy** button in the top-right):
!!! example "getting_started.py"
+
```py
--8<-- "examples/getting_started.py"
```
+
## Basic Application
@@ -31,6 +33,7 @@ following contents:
```py
#!/usr/bin/env python
"""A basic cmd2 application."""
+
import cmd2
@@ -38,8 +41,9 @@ class BasicApp(cmd2.Cmd):
"""Cmd2 application to demonstrate many common features."""
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
app = BasicApp()
sys.exit(app.cmdloop())
```
@@ -69,7 +73,7 @@ def __init__(self):
# Make maxrepeats settable at runtime
self.maxrepeats = 3
- self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command', self))
+ self.add_settable(cmd2.Settable("maxrepeats", int, "max repetitions for speak command", self))
```
In that initializer, the first thing to do is to make sure we initialize `cmd2`. That's what the
@@ -94,10 +98,11 @@ that the `speak_parser` attribute and the `do_speak()` method are part of the `B
```py
speak_parser = cmd2.Cmd2ArgumentParser()
-speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
-speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
-speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
-speak_parser.add_argument('words', nargs='+', help='words to say')
+speak_parser.add_argument("-p", "--piglatin", action="store_true", help="atinLay")
+speak_parser.add_argument("-s", "--shout", action="store_true", help="N00B EMULATION MODE")
+speak_parser.add_argument("-r", "--repeat", type=int, help="output [n] times")
+speak_parser.add_argument("words", nargs="+", help="words to say")
+
@cmd2.with_argparser(speak_parser)
def do_speak(self, args):
@@ -105,14 +110,14 @@ def do_speak(self, args):
words = []
for word in args.words:
if args.piglatin:
- word = '%s%say' % (word[1:], word[0])
+ word = "%s%say" % (word[1:], word[0])
if args.shout:
word = word.upper()
words.append(word)
repetitions = args.repeat or 1
for _ in range(min(repetitions, self.maxrepeats)):
# .poutput handles newlines, and accommodates output redirection too
- self.poutput(' '.join(words))
+ self.poutput(" ".join(words))
```
Up at the top of the script, you'll also need to add:
@@ -186,12 +191,12 @@ Let's add a shortcut for our `speak` command. Change the `__init__()` method so
```py
def __init__(self):
shortcuts = cmd2.DEFAULT_SHORTCUTS
- shortcuts.update({'&': 'speak'})
+ shortcuts.update({"&": "speak"})
super().__init__(shortcuts=shortcuts)
# Make maxrepeats settable at runtime
self.maxrepeats = 3
- self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command', self))
+ self.add_settable(cmd2.Settable("maxrepeats", int, "max repetitions for speak command", self))
```
Shortcuts are passed to the `cmd2` initializer, and if you want the built-in shortcuts of `cmd2` you
@@ -224,14 +229,15 @@ def do_speak(self, args):
words = []
for word in args.words:
if args.piglatin:
- word = '%s%say' % (word[1:], word[0])
+ word = "%s%say" % (word[1:], word[0])
if args.shout:
word = word.upper()
words.append(word)
repetitions = args.repeat or 1
for _ in range(min(repetitions, self.maxrepeats)):
# .poutput handles newlines, and accommodates output redirection too
- self.poutput(' '.join(words))
+ self.poutput(" ".join(words))
+
# orate is a synonym for speak which takes multiline input
do_orate = do_speak
@@ -241,7 +247,7 @@ With the new command created, we need to tell `cmd2` to treat that command as a
Modify the super initialization line to look like this:
```py
-super().__init__(multiline_commands=['orate'], shortcuts=shortcuts)
+super().__init__(multiline_commands=["orate"], shortcuts=shortcuts)
```
Now when you run the example, you can type something like this:
diff --git a/docs/features/annotated.md b/docs/features/annotated.md
index 98d087a97..ec2f790aa 100644
--- a/docs/features/annotated.md
+++ b/docs/features/annotated.md
@@ -31,9 +31,10 @@ The two decorators are interchangeable -- here is the same command written both
```py
parser = Cmd2ArgumentParser()
- parser.add_argument('name', help='person to greet')
- parser.add_argument('--count', type=int, default=1, help='repetitions')
- parser.add_argument('--loud', action='store_true', help='shout')
+ parser.add_argument("name", help="person to greet")
+ parser.add_argument("--count", type=int, default=1, help="repetitions")
+ parser.add_argument("--loud", action="store_true", help="shout")
+
@with_argparser(parser)
def do_greet(self, args):
@@ -61,6 +62,7 @@ Underscores in parameter names are converted to dashes in the generated flag, so
```py
from cmd2.annotated import with_annotated
+
class MyApp(cmd2.Cmd):
@with_annotated
def do_greet(self, name: str, count: int = 1, loud: bool = False):
@@ -132,6 +134,7 @@ For finer control, use `typing.Annotated` with [Argument][cmd2.annotated.Argumen
from typing import Annotated
from cmd2.annotated import Argument, Option, with_annotated
+
class MyApp(cmd2.Cmd):
def sport_choices(self) -> cmd2.Choices:
return cmd2.Choices.from_values(["football", "basketball"])
@@ -139,15 +142,22 @@ class MyApp(cmd2.Cmd):
@with_annotated
def do_play(
self,
- sport: Annotated[str, Argument(
- choices_provider=sport_choices,
- help_text="Sport to play",
- )],
- venue: Annotated[str, Option(
- "--venue", "-v",
- help_text="Where to play",
- completer=cmd2.Cmd.path_complete,
- )] = "home",
+ sport: Annotated[
+ str,
+ Argument(
+ choices_provider=sport_choices,
+ help_text="Sport to play",
+ ),
+ ],
+ venue: Annotated[
+ str,
+ Option(
+ "--venue",
+ "-v",
+ help_text="Where to play",
+ completer=cmd2.Cmd.path_complete,
+ ),
+ ] = "home",
):
self.poutput(f"Playing {sport} at {venue}")
```
@@ -173,6 +183,7 @@ import enum
from typing import Annotated
from cmd2.annotated import Argument, with_annotated
+
class Color(enum.Enum):
red = "red"
green = "green"
@@ -183,6 +194,7 @@ class Color(enum.Enum):
# map a special keyword onto a real member; return None to reject
return cls.red if str(value).lower() == "auto" else None
+
class MyApp(cmd2.Cmd):
@with_annotated
def do_theme(self, choice: Annotated[Color, Argument(allow_unknown_entry=True)]) -> None:
@@ -265,6 +277,7 @@ class UpperAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values.upper())
+
@with_annotated
def do_shout(self, name: Annotated[str, Option("--name", action=UpperAction)] = ""):
self.poutput(name)
@@ -298,6 +311,7 @@ forms are equivalent:
# Signature default
def do_x(self, name: Annotated[str, Option("--name")] = "HI"): ...
+
# Metadata default (same behaviour)
def do_x(self, name: Annotated[str, Option("--name", default="HI")]): ...
```
@@ -359,11 +373,13 @@ import datetime
from typing import Annotated
from cmd2.annotated import Argument, Option, with_annotated
+
def parse_size(value: str) -> int:
"""Parse an integer with an optional K/M/G suffix."""
multiplier = {"K": 1_000, "M": 1_000_000, "G": 1_000_000_000}.get(value[-1:].upper(), 1)
return int(value[:-1] if multiplier != 1 else value) * multiplier
+
class MyApp(cmd2.Cmd):
@with_annotated
def do_alloc(self, size: Annotated[int, Argument(converter=parse_size)]) -> None:
@@ -382,9 +398,11 @@ instead infer `nargs` and split the input across several tokens:
```py
from typing import Annotated, Any
+
def parse_intset(value: str) -> set[int]:
return {int(piece) for piece in value.split(",")}
+
@with_annotated
def do_select(self, idx: Annotated[Any, Option("--idx", converter=parse_intset)]) -> None:
self.poutput(sorted(idx)) # `select --idx 1,3,5` -> [1, 3, 5]
@@ -404,6 +422,7 @@ import os
from typing import Annotated
from cmd2.annotated import Argument, with_annotated
+
class MyApp(cmd2.Cmd):
@with_annotated
def do_tag(self, color: Annotated[Color, Argument(preprocess=str.lower)]) -> None:
@@ -486,6 +505,7 @@ and `description` for a titled help section (omit them for an untitled group):
```py
from cmd2.annotated import Group, with_annotated
+
class App(cmd2.Cmd):
@with_annotated(
description="Open a network connection.",
@@ -509,6 +529,8 @@ def do_greet(self, name: str):
:param name: who to greet
"""
self.poutput(f"hello {name}")
+
+
# parser.description == "Greet someone by name."
```
@@ -532,9 +554,7 @@ choice reads as `[--json | --csv]` instead of expanding to `--json`/`--no-json`
```py
@with_annotated(
- mutually_exclusive_groups=(
- Group("json", "csv", title="output", description="how to write results"),
- ),
+ mutually_exclusive_groups=(Group("json", "csv", title="output", description="how to write results"),),
)
def do_render(
self,
@@ -560,6 +580,7 @@ class Conn(ArgumentBlock):
host: Annotated[str, Option("--host")] = "localhost"
port: Annotated[int, Option("--port")] = 8080
+
@with_annotated(groups=(Group("host", "port", title="connection"),))
def do_connect(self, conn: Conn) -> None: ...
```
@@ -611,6 +632,7 @@ def do_manage(self, *, cmd2_subcommand_func):
if cmd2_subcommand_func:
cmd2_subcommand_func()
+
@with_annotated(subcommand_to="manage", help="list projects")
def manage_list(self):
self.poutput("listing")
@@ -626,6 +648,7 @@ def manage_project(self, *, cmd2_subcommand_func):
if cmd2_subcommand_func:
cmd2_subcommand_func()
+
@with_annotated(subcommand_to="manage project", help="add a project")
def manage_project_add(self, name: str):
self.poutput(f"added {name}")
@@ -770,9 +793,11 @@ decorator, it skips the first parameter as the method receiver (`self`/`cls`).
```py
from cmd2.annotated import build_parser_from_function
+
def greet(self, name: str, count: int = 1):
"""Greet someone."""
+
parser = build_parser_from_function(greet)
namespace = parser.parse_args(["Alice", "--count", "3"])
# namespace.name == "Alice", namespace.count == 3
diff --git a/docs/features/argument_processing.md b/docs/features/argument_processing.md
index aeadf7c8d..145965b15 100644
--- a/docs/features/argument_processing.md
+++ b/docs/features/argument_processing.md
@@ -81,17 +81,18 @@ Here's what it looks like:
from cmd2 import Cmd2ArgumentParser, with_argparser
argparser = Cmd2ArgumentParser()
-argparser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
-argparser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
-argparser.add_argument('-r', '--repeat', type=int, help='output [n] times')
-argparser.add_argument('word', nargs='?', help='word to say')
+argparser.add_argument("-p", "--piglatin", action="store_true", help="atinLay")
+argparser.add_argument("-s", "--shout", action="store_true", help="N00B EMULATION MODE")
+argparser.add_argument("-r", "--repeat", type=int, help="output [n] times")
+argparser.add_argument("word", nargs="?", help="word to say")
+
@with_argparser(argparser)
def do_speak(self, opts):
"""Repeats what you tell me to."""
arg = opts.word
if opts.piglatin:
- arg = '%s%say' % (arg[1:], arg[0])
+ arg = "%s%say" % (arg[1:], arg[0])
if opts.shout:
arg = arg.upper()
repetitions = opts.repeat or 1
@@ -125,13 +126,15 @@ With this code:
from cmd2 import Cmd2ArgumentParser, with_argparser
argparser = Cmd2ArgumentParser()
-argparser.add_argument('tag', help='tag')
-argparser.add_argument('content', nargs='+', help='content to surround with tag')
+argparser.add_argument("tag", help="tag")
+argparser.add_argument("content", nargs="+", help="content to surround with tag")
+
+
@with_argparser(argparser)
def do_tag(self, args):
"""Create an HTML tag"""
- self.stdout.write('<{0}>{1}{0}>'.format(args.tag, ' '.join(args.content)))
- self.stdout.write('\n')
+ self.stdout.write("<{0}>{1}{0}>".format(args.tag, " ".join(args.content)))
+ self.stdout.write("\n")
```
the `help tag` command displays:
@@ -155,13 +158,15 @@ leave the docstring on your method blank:
```py
from cmd2 import Cmd2ArgumentParser, with_argparser
-argparser = Cmd2ArgumentParser(description='create an HTML tag')
-argparser.add_argument('tag', help='tag')
-argparser.add_argument('content', nargs='+', help='content to surround with tag')
+argparser = Cmd2ArgumentParser(description="create an HTML tag")
+argparser.add_argument("tag", help="tag")
+argparser.add_argument("content", nargs="+", help="content to surround with tag")
+
+
@with_argparser(argparser)
def do_tag(self, args):
- self.stdout.write('<{0}>{1}{0}>'.format(args.tag, ' '.join(args.content)))
- self.stdout.write('\n')
+ self.stdout.write("<{0}>{1}{0}>".format(args.tag, " ".join(args.content)))
+ self.stdout.write("\n")
```
Now when the user enters `help tag` they see:
@@ -184,14 +189,17 @@ To add additional text to the end of the generated help message, use the `epilog
```py
from cmd2 import Cmd2ArgumentParser, with_argparser
-argparser = Cmd2ArgumentParser(description='create an HTML tag',
- epilog='This command cannot generate tags with no content, like
.')
-argparser.add_argument('tag', help='tag')
-argparser.add_argument('content', nargs='+', help='content to surround with tag')
+argparser = Cmd2ArgumentParser(
+ description="create an HTML tag", epilog="This command cannot generate tags with no content, like
."
+)
+argparser.add_argument("tag", help="tag")
+argparser.add_argument("content", nargs="+", help="content to surround with tag")
+
+
@with_argparser(argparser)
def do_tag(self, args):
- self.stdout.write('<{0}>{1}{0}>'.format(args.tag, ' '.join(args.content)))
- self.stdout.write('\n')
+ self.stdout.write("<{0}>{1}{0}>".format(args.tag, " ".join(args.content)))
+ self.stdout.write("\n")
```
Which yields:
@@ -248,7 +256,7 @@ additional attributes that may be helpful, including `arg_list` and `argv`:
```py
class CmdLineApp(cmd2.Cmd):
- """ Example cmd2 application. """
+ """Example cmd2 application."""
def do_say(self, statement):
# statement contains a string
@@ -276,8 +284,9 @@ methods that should receive an argument list instead of a string:
```py
from cmd2 import with_argument_list
+
class CmdLineApp(cmd2.Cmd):
- """ Example cmd2 application. """
+ """Example cmd2 application."""
def do_say(self, cmdline):
# cmdline contains a string
@@ -300,8 +309,8 @@ Here's what it looks like:
from cmd2 import Cmd2ArgumentParser, with_argparser
dir_parser = Cmd2ArgumentParser()
-dir_parser.add_argument('-l', '--long', action='store_true',
- help="display in long format with one item per line")
+dir_parser.add_argument("-l", "--long", action="store_true", help="display in long format with one item per line")
+
@with_argparser(dir_parser, with_unknown_args=True)
def do_dir(self, args, unknown):
@@ -309,8 +318,8 @@ def do_dir(self, args, unknown):
# No arguments for this command
if unknown:
self.perror("dir does not take any positional arguments:")
- self.do_help('dir')
- self.last_result = 'Bad arguments'
+ self.do_help("dir")
+ self.last_result = "Bad arguments"
return
# Get the contents as a list
diff --git a/docs/features/async_commands.md b/docs/features/async_commands.md
index c8430d4ae..0cc5915ba 100644
--- a/docs/features/async_commands.md
+++ b/docs/features/async_commands.md
@@ -32,6 +32,7 @@ import cmd2
_event_loop = None
_event_lock = threading.Lock()
+
def _get_event_loop() -> asyncio.AbstractEventLoop:
"""Get or create the background event loop."""
global _event_loop
@@ -42,22 +43,26 @@ def _get_event_loop() -> asyncio.AbstractEventLoop:
_event_loop = asyncio.new_event_loop()
thread = threading.Thread(
target=_event_loop.run_forever,
- name='Async Runner',
+ name="Async Runner",
daemon=True,
)
thread.start()
return _event_loop
+
def with_async_loop(func: Callable[..., Any]) -> Callable[..., Any]:
"""Decorator to run a command method asynchronously in a background thread."""
+
@functools.wraps(func)
def wrapper(self: cmd2.Cmd, *args: Any, **kwargs: Any) -> Any:
loop = _get_event_loop()
coro = func(self, *args, **kwargs)
future = asyncio.run_coroutine_threadsafe(coro, loop)
return future.result()
+
return wrapper
+
class AsyncApp(cmd2.Cmd):
@with_async_loop
async def do_my_async(self, _: cmd2.Statement) -> None:
diff --git a/docs/features/builtin_commands.md b/docs/features/builtin_commands.md
index 8957a1f0f..f2751f8ae 100644
--- a/docs/features/builtin_commands.md
+++ b/docs/features/builtin_commands.md
@@ -125,5 +125,5 @@ from your application:
class NoShellApp(cmd2.Cmd):
"""A simple cmd2 application."""
- delattr(cmd2.Cmd, 'do_shell')
+ delattr(cmd2.Cmd, "do_shell")
```
diff --git a/docs/features/commands.md b/docs/features/commands.md
index 21a7864a9..df46f1f1a 100644
--- a/docs/features/commands.md
+++ b/docs/features/commands.md
@@ -15,6 +15,7 @@ The simplest `cmd2` application looks like this:
```py
#!/usr/bin/env python
"""A simple cmd2 application."""
+
import cmd2
@@ -22,8 +23,9 @@ class App(cmd2.Cmd):
"""A simple cmd2 application."""
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
c = App()
sys.exit(c.cmdloop())
```
@@ -142,20 +144,24 @@ You can use this capability to easily return your own values to the operating sy
```py
#!/usr/bin/env python
"""A simple cmd2 application."""
+
import cmd2
class App(cmd2.Cmd):
"""A simple cmd2 application."""
+
def do_bail(self, line):
"""Exit the application"""
self.perror("fatal error, exiting")
self.exit_code = 2
return True
-if __name__ == '__main__':
+
+if __name__ == "__main__":
import sys
+
c = App()
sys.exit(c.cmdloop())
```
diff --git a/docs/features/disable_commands.md b/docs/features/disable_commands.md
index 1a22f6541..37e1dae50 100644
--- a/docs/features/disable_commands.md
+++ b/docs/features/disable_commands.md
@@ -40,22 +40,23 @@ the `hidden_commands` list:
```py
class HiddenCommands(cmd2.Cmd):
"""An app which demonstrates how to hide a command"""
+
def __init__(self):
super().__init__()
- self.hidden_commands.append('py')
+ self.hidden_commands.append("py")
```
As shown above, you would typically do this as part of initializing your application. If you decide
you want to unhide a command later in the execution of your application, you can by doing:
```py
-self.hidden_commands = [cmd for cmd in self.hidden_commands if cmd != 'py']
+self.hidden_commands = [cmd for cmd in self.hidden_commands if cmd != "py"]
```
You might be thinking that the list comprehension is overkill and you'd rather do something like:
```py
-self.hidden_commands.remove('py')
+self.hidden_commands.remove("py")
```
You may be right, but `remove()` will raise a `ValueError` if `py` isn't in the list, and it will
@@ -75,16 +76,16 @@ class DisabledCommands(cmd2.Cmd):
"""An application which disables and enables commands"""
def do_lock(self, line):
- self.disable_command('open', "you can't open the door because it is locked")
- self.poutput('the door is locked')
+ self.disable_command("open", "you can't open the door because it is locked")
+ self.poutput("the door is locked")
def do_unlock(self, line):
- self.enable_command('open')
- self.poutput('the door is unlocked')
+ self.enable_command("open")
+ self.poutput("the door is unlocked")
def do_open(self, line):
"""open the door"""
- self.poutput('opening the door')
+ self.poutput("opening the door")
```
This method has the added benefit of removing disabled commands from the help menu. But, this method
@@ -99,14 +100,14 @@ all the commands in a category with a single method call. Say you have created a
commands called "Server Information". You can disable all commands in that category:
```py
-not_connected_msg = 'You must be connected to use this command'
-self.disable_category('Server Information', not_connected_msg)
+not_connected_msg = "You must be connected to use this command"
+self.disable_category("Server Information", not_connected_msg)
```
Similarly, you can re-enable all the commands in a category:
```py
-self.enable_category('Server Information')
+self.enable_category("Server Information")
```
See [help_categories.py](https://github.com/python-cmd2/cmd2/blob/main/examples/help_categories.py)
diff --git a/docs/features/embedded_python_shells.md b/docs/features/embedded_python_shells.md
index 0a4b60f42..8d693a3fe 100644
--- a/docs/features/embedded_python_shells.md
+++ b/docs/features/embedded_python_shells.md
@@ -7,6 +7,8 @@ will be present and run an interactive Python shell:
```py
from cmd2 import Cmd
+
+
class App(Cmd):
def __init__(self):
Cmd.__init__(self, include_py=True)
@@ -59,6 +61,8 @@ interactive IPython shell:
```py
from cmd2 import Cmd
+
+
class App(Cmd):
def __init__(self):
Cmd.__init__(self, include_ipy=True)
diff --git a/docs/features/help.md b/docs/features/help.md
index 11150ee46..8dee6fba5 100644
--- a/docs/features/help.md
+++ b/docs/features/help.md
@@ -70,7 +70,7 @@ By default, `cmd2.Cmd` defines its `DEFAULT_CATEGORY` as `"Cmd2 Commands"`.
```py
class MyApp(cmd2.Cmd):
# All commands defined in this class will be grouped here
- DEFAULT_CATEGORY = 'Application Commands'
+ DEFAULT_CATEGORY = "Application Commands"
def do_echo(self, arg):
"""Echo command"""
@@ -81,11 +81,11 @@ This also works for [Command Sets](./modular_commands.md):
```py
class Plugin(cmd2.CommandSet):
- DEFAULT_CATEGORY = 'Plugin Commands'
+ DEFAULT_CATEGORY = "Plugin Commands"
def do_plugin_cmd(self, _):
"""Plugin command"""
- self._cmd.poutput('Plugin')
+ self._cmd.poutput("Plugin")
```
When using inheritance, `cmd2` uses the `DEFAULT_CATEGORY` of the class where the command was
@@ -98,10 +98,10 @@ If you want to rename the built-in category itself, you can do so by reassigning
```py
class MyApp(cmd2.Cmd):
# Rename the framework's built-in category
- cmd2.Cmd.DEFAULT_CATEGORY = 'Shell Commands'
+ cmd2.Cmd.DEFAULT_CATEGORY = "Shell Commands"
# Set the category for your own commands
- DEFAULT_CATEGORY = 'Application Commands'
+ DEFAULT_CATEGORY = "Application Commands"
```
For a complete demonstration of this functionality, see the
@@ -117,10 +117,10 @@ precedence over the `DEFAULT_CATEGORY`.
Using the `@with_category` decorator:
```py
-@with_category('Connecting')
+@with_category("Connecting")
def do_which(self, _):
"""Which command"""
- self.poutput('Which')
+ self.poutput("Which")
```
Using the `categorize()` function:
@@ -130,7 +130,8 @@ You can call with a single function:
```py
def do_connect(self, _):
"""Connect command"""
- self.poutput('Connect')
+ self.poutput("Connect")
+
# Tag the above command functions under the category Connecting
categorize(do_connect, CMD_CAT_CONNECTING)
@@ -141,20 +142,21 @@ Or with an Iterable container of functions:
```py
def do_undeploy(self, _):
"""Undeploy command"""
- self.poutput('Undeploy')
+ self.poutput("Undeploy")
+
def do_stop(self, _):
"""Stop command"""
- self.poutput('Stop')
+ self.poutput("Stop")
+
def do_findleakers(self, _):
"""Find Leakers command"""
- self.poutput('Find Leakers')
+ self.poutput("Find Leakers")
+
# Tag the above command functions under the category Application Management
-categorize((do_undeploy,
- do_stop,
- do_findleakers), CMD_CAT_APP_MGMT)
+categorize((do_undeploy, do_stop, do_findleakers), CMD_CAT_APP_MGMT)
```
The `help` command also has a verbose option (`help -v` or `help --verbose`) that combines the help
diff --git a/docs/features/hooks.md b/docs/features/hooks.md
index 6fa59bb38..a34f70b98 100644
--- a/docs/features/hooks.md
+++ b/docs/features/hooks.md
@@ -172,8 +172,8 @@ simple example which shows the proper technique:
```py
def myhookmethod(self, params: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
- if not '|' in params.statement.raw:
- newinput = params.statement.raw + ' | less'
+ if not "|" in params.statement.raw:
+ newinput = params.statement.raw + " | less"
params.statement = self.statement_parser.parse(newinput)
return params
```
diff --git a/docs/features/initialization.md b/docs/features/initialization.md
index ea93b2d78..fc084ff3d 100644
--- a/docs/features/initialization.md
+++ b/docs/features/initialization.md
@@ -4,9 +4,11 @@ Here is a basic example `cmd2` application which demonstrates many capabilities
!!! example "examples/getting_started.py"
+
```py
--8<-- "examples/getting_started.py"
```
+
## Cmd class initializer
diff --git a/docs/features/misc.md b/docs/features/misc.md
index 7e5fa9628..a8fe7f723 100644
--- a/docs/features/misc.md
+++ b/docs/features/misc.md
@@ -20,10 +20,10 @@ Presents numbered options to user, as bash `select`.
```py
def do_eat(self, arg):
- sauce = self.select('sweet salty', 'Sauce? ')
- result = '{food} with {sauce} sauce, yum!'
+ sauce = self.select("sweet salty", "Sauce? ")
+ result = "{food} with {sauce} sauce, yum!"
result = result.format(food=arg, sauce=sauce)
- self.stdout.write(result + '\n')
+ self.stdout.write(result + "\n")
```
```text
diff --git a/docs/features/modular_commands.md b/docs/features/modular_commands.md
index dbd9c5d86..28c775eef 100644
--- a/docs/features/modular_commands.md
+++ b/docs/features/modular_commands.md
@@ -52,30 +52,33 @@ initializer arguments, see [Manual CommandSet Construction](#manual-commandset-c
import cmd2
from cmd2 import CommandSet
+
class ExampleApp(cmd2.Cmd):
"""
CommandSets are automatically loaded. Nothing needs to be done.
"""
+
def __init__(self, *args, **kwargs):
super().__init__(*args, auto_load_commands=True, **kwargs)
def do_something(self, arg):
"""Something Command."""
- self.poutput('this is the something command')
+ self.poutput("this is the something command")
+
class AutoLoadCommandSet(CommandSet[ExampleApp]):
- DEFAULT_CATEGORY = 'My Category'
+ DEFAULT_CATEGORY = "My Category"
def __init__(self):
super().__init__()
def do_hello(self, _: cmd2.Statement):
"""Hello Command."""
- self._cmd.poutput('Hello')
+ self._cmd.poutput("Hello")
def do_world(self, _: cmd2.Statement):
"""World Command."""
- self._cmd.poutput('World')
+ self._cmd.poutput("World")
```
### Manual CommandSet Construction
@@ -87,10 +90,12 @@ construct CommandSets and pass in the initializer to Cmd2.
import cmd2
from cmd2 import CommandSet
+
class ExampleApp(cmd2.Cmd):
"""
CommandSets with initializer parameters are provided in the initializer
"""
+
def __init__(self, *args, **kwargs):
# gotta have this or neither the plugin or cmd2 will initialize
super().__init__(*args, auto_load_commands=True, **kwargs)
@@ -98,10 +103,11 @@ class ExampleApp(cmd2.Cmd):
def do_something(self, arg):
"""Something Command."""
self.last_result = 5
- self.poutput('this is the something command')
+ self.poutput("this is the something command")
+
class CustomInitCommandSet(CommandSet[ExampleApp]):
- DEFAULT_CATEGORY = 'My Category'
+ DEFAULT_CATEGORY = "My Category"
def __init__(self, arg1, arg2):
super().__init__()
@@ -111,11 +117,11 @@ class CustomInitCommandSet(CommandSet[ExampleApp]):
def do_show_arg1(self, _: cmd2.Statement):
"""Show Arg 1."""
- self._cmd.poutput(f'Arg1: {self._arg1}')
+ self._cmd.poutput(f"Arg1: {self._arg1}")
def do_show_arg2(self, _: cmd2.Statement):
"""Show Arg 2."""
- self._cmd.poutput(f'Arg2: {self._arg2}')
+ self._cmd.poutput(f"Arg2: {self._arg2}")
def main():
@@ -139,11 +145,13 @@ validation when accessing custom attributes or methods on your main application
import cmd2
from cmd2 import CommandSet
+
class MyApp(cmd2.Cmd):
def __init__(self):
super().__init__()
self.custom_state = "Some important data"
+
class MyCommands(CommandSet[MyApp]):
def do_check_state(self, _: cmd2.Statement):
# Type checkers know self._cmd is an instance of MyApp
@@ -165,33 +173,33 @@ from cmd2 import CommandSet, with_argparser, with_category
class LoadableFruits(CommandSet["ExampleApp"]):
- DEFAULT_CATEGORY = 'Fruits'
+ DEFAULT_CATEGORY = "Fruits"
def __init__(self):
super().__init__()
def do_apple(self, _: cmd2.Statement):
"""Apple Command."""
- self._cmd.poutput('Apple')
+ self._cmd.poutput("Apple")
def do_banana(self, _: cmd2.Statement):
"""Banana Command."""
- self._cmd.poutput('Banana')
+ self._cmd.poutput("Banana")
class LoadableVegetables(CommandSet["ExampleApp"]):
- DEFAULT_CATEGORY = 'Vegetables'
+ DEFAULT_CATEGORY = "Vegetables"
def __init__(self):
super().__init__()
def do_arugula(self, _: cmd2.Statement):
"""Arugula Command."""
- self._cmd.poutput('Arugula')
+ self._cmd.poutput("Arugula")
def do_bokchoy(self, _: cmd2.Statement):
"""Bok Choy Command."""
- self._cmd.poutput('Bok Choy')
+ self._cmd.poutput("Bok Choy")
class ExampleApp(cmd2.Cmd):
@@ -207,39 +215,39 @@ class ExampleApp(cmd2.Cmd):
self._vegetables = LoadableVegetables()
load_parser = cmd2.Cmd2ArgumentParser()
- load_parser.add_argument('cmds', choices=['fruits', 'vegetables'])
+ load_parser.add_argument("cmds", choices=["fruits", "vegetables"])
@with_argparser(load_parser)
- @with_category('Command Loading')
+ @with_category("Command Loading")
def do_load(self, ns: argparse.Namespace):
"""Load Command."""
- if ns.cmds == 'fruits':
+ if ns.cmds == "fruits":
try:
self.register_command_set(self._fruits)
- self.poutput('Fruits loaded')
+ self.poutput("Fruits loaded")
except ValueError:
- self.poutput('Fruits already loaded')
+ self.poutput("Fruits already loaded")
- if ns.cmds == 'vegetables':
+ if ns.cmds == "vegetables":
try:
self.register_command_set(self._vegetables)
- self.poutput('Vegetables loaded')
+ self.poutput("Vegetables loaded")
except ValueError:
- self.poutput('Vegetables already loaded')
+ self.poutput("Vegetables already loaded")
@with_argparser(load_parser)
def do_unload(self, ns: argparse.Namespace):
"""Unload Command."""
- if ns.cmds == 'fruits':
+ if ns.cmds == "fruits":
self.unregister_command_set(self._fruits)
- self.poutput('Fruits unloaded')
+ self.poutput("Fruits unloaded")
- if ns.cmds == 'vegetables':
+ if ns.cmds == "vegetables":
self.unregister_command_set(self._vegetables)
- self.poutput('Vegetables unloaded')
+ self.poutput("Vegetables unloaded")
-if __name__ == '__main__':
+if __name__ == "__main__":
app = ExampleApp()
app.cmdloop()
```
@@ -296,41 +304,41 @@ from cmd2 import CommandSet, with_argparser, with_category
class LoadableFruits(CommandSet["ExampleApp"]):
- DEFAULT_CATEGORY = 'Fruits'
+ DEFAULT_CATEGORY = "Fruits"
def __init__(self):
super().__init__()
def do_apple(self, _: cmd2.Statement):
"""Apple Command."""
- self._cmd.poutput('Apple')
+ self._cmd.poutput("Apple")
banana_parser = cmd2.Cmd2ArgumentParser()
- banana_parser.add_argument('direction', choices=['discs', 'lengthwise'])
+ banana_parser.add_argument("direction", choices=["discs", "lengthwise"])
- @cmd2.as_subcommand_to('cut', 'banana', banana_parser)
+ @cmd2.as_subcommand_to("cut", "banana", banana_parser)
def cut_banana(self, ns: argparse.Namespace):
"""Cut banana"""
- self._cmd.poutput('cutting banana: ' + ns.direction)
+ self._cmd.poutput("cutting banana: " + ns.direction)
class LoadableVegetables(CommandSet["ExampleApp"]):
- DEFAULT_CATEGORY = 'Vegetables'
+ DEFAULT_CATEGORY = "Vegetables"
def __init__(self):
super().__init__()
def do_arugula(self, _: cmd2.Statement):
"""Arugula Command."""
- self._cmd.poutput('Arugula')
+ self._cmd.poutput("Arugula")
bokchoy_parser = cmd2.Cmd2ArgumentParser()
- bokchoy_parser.add_argument('style', choices=['quartered', 'diced'])
+ bokchoy_parser.add_argument("style", choices=["quartered", "diced"])
- @cmd2.as_subcommand_to('cut', 'bokchoy', bokchoy_parser)
+ @cmd2.as_subcommand_to("cut", "bokchoy", bokchoy_parser)
def cut_bokchoy(self, _: argparse.Namespace):
"""Cut bok choy."""
- self._cmd.poutput('Bok Choy')
+ self._cmd.poutput("Bok Choy")
class ExampleApp(cmd2.Cmd):
@@ -346,36 +354,36 @@ class ExampleApp(cmd2.Cmd):
self._vegetables = LoadableVegetables()
load_parser = cmd2.Cmd2ArgumentParser()
- load_parser.add_argument('cmds', choices=['fruits', 'vegetables'])
+ load_parser.add_argument("cmds", choices=["fruits", "vegetables"])
@with_argparser(load_parser)
- @with_category('Command Loading')
+ @with_category("Command Loading")
def do_load(self, ns: argparse.Namespace):
"""Load Command."""
- if ns.cmds == 'fruits':
+ if ns.cmds == "fruits":
try:
self.register_command_set(self._fruits)
- self.poutput('Fruits loaded')
+ self.poutput("Fruits loaded")
except ValueError:
- self.poutput('Fruits already loaded')
+ self.poutput("Fruits already loaded")
- if ns.cmds == 'vegetables':
+ if ns.cmds == "vegetables":
try:
self.register_command_set(self._vegetables)
- self.poutput('Vegetables loaded')
+ self.poutput("Vegetables loaded")
except ValueError:
- self.poutput('Vegetables already loaded')
+ self.poutput("Vegetables already loaded")
@with_argparser(load_parser)
def do_unload(self, ns: argparse.Namespace):
"""Unload Command."""
- if ns.cmds == 'fruits':
+ if ns.cmds == "fruits":
self.unregister_command_set(self._fruits)
- self.poutput('Fruits unloaded')
+ self.poutput("Fruits unloaded")
- if ns.cmds == 'vegetables':
+ if ns.cmds == "vegetables":
self.unregister_command_set(self._vegetables)
- self.poutput('Vegetables unloaded')
+ self.poutput("Vegetables unloaded")
cut_parser = cmd2.Cmd2ArgumentParser()
cut_parser.add_subparsers(title="item", help="item to cut", metavar="ITEM", required=True)
@@ -387,8 +395,7 @@ class ExampleApp(cmd2.Cmd):
ns.cmd2_subcommand_func(ns)
-
-if __name__ == '__main__':
+if __name__ == "__main__":
app = ExampleApp()
app.cmdloop()
```
diff --git a/docs/features/plugins.md b/docs/features/plugins.md
index 62fc9ab22..0c9bec76d 100644
--- a/docs/features/plugins.md
+++ b/docs/features/plugins.md
@@ -28,8 +28,10 @@ and an example app which uses the plugin:
import cmd2
import cmd2_myplugin
+
class Example(cmd2_myplugin.MyPlugin, cmd2.Cmd):
"""An class to show how to use a plugin"""
+
def __init__(self, *args, **kwargs):
# code placed here runs before cmd2.Cmd or
# any plugins initialize
@@ -75,8 +77,8 @@ class MyPlugin:
# code placed here runs before cmd2.Cmd initializes
super().__init__(*args, **kwargs)
# code placed here runs after cmd2.Cmd initializes
- self.mysetting = 'somevalue'
- self.add_settable(cmd2.Settable('mysetting', str, 'short help message for mysetting', self))
+ self.mysetting = "somevalue"
+ self.add_settable(cmd2.Settable("mysetting", str, "short help message for mysetting", self))
```
You can hide settings from the user by calling [cmd2.Cmd.remove_settable][]. See
@@ -119,7 +121,7 @@ class MyPlugin:
def cmd2_myplugin_postparsing_hook(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
"""Method to be called after parsing user input, but before running the command"""
- self.poutput('in postparsing_hook')
+ self.poutput("in postparsing_hook")
return data
```
diff --git a/docs/features/prompt.md b/docs/features/prompt.md
index 93fb6b495..0f8a09082 100644
--- a/docs/features/prompt.md
+++ b/docs/features/prompt.md
@@ -79,14 +79,15 @@ You can customize the content of the toolbar by overriding the [cmd2.Cmd.get_bot
method.
```py
- from prompt_toolkit.formatted_text import AnyFormattedText
-
- def get_bottom_toolbar(self) -> AnyFormattedText:
- return [
- ('ansigreen', 'My Application Name'),
- ('', ' - '),
- ('ansiyellow', 'Current Status: Idle'),
- ]
+from prompt_toolkit.formatted_text import AnyFormattedText
+
+
+def get_bottom_toolbar(self) -> AnyFormattedText:
+ return [
+ ("ansigreen", "My Application Name"),
+ ("", " - "),
+ ("ansiyellow", "Current Status: Idle"),
+ ]
```
### Refreshing the Toolbar
diff --git a/docs/features/redirection.md b/docs/features/redirection.md
index 8b2ab68e4..27a238caa 100644
--- a/docs/features/redirection.md
+++ b/docs/features/redirection.md
@@ -49,6 +49,8 @@ output of that to a file called _output.txt_.
```py
from cmd2 import Cmd
+
+
class App(Cmd):
def __init__(self):
super().__init__(allow_redirection=False)
diff --git a/docs/features/scripting.md b/docs/features/scripting.md
index 429fba210..531027afc 100644
--- a/docs/features/scripting.md
+++ b/docs/features/scripting.md
@@ -154,26 +154,27 @@ As a baseline, let's start with the following `cmd2` application called `FirstAp
```py
#!/usr/bin/env python
"""A simple cmd2 application."""
+
import cmd2
class FirstApp(cmd2.Cmd):
"""A simple cmd2 application."""
+
def __init__(self):
shortcuts = cmd2.DEFAULT_SHORTCUTS
- shortcuts.update({'&': 'speak'})
+ shortcuts.update({"&": "speak"})
super().__init__(shortcuts=shortcuts)
# Make maxrepeats settable at runtime
self.maxrepeats = 3
- self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command', self))
-
+ self.add_settable(cmd2.Settable("maxrepeats", int, "max repetitions for speak command", self))
speak_parser = cmd2.Cmd2ArgumentParser()
- speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
- speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
- speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
- speak_parser.add_argument('words', nargs='+', help='words to say')
+ speak_parser.add_argument("-p", "--piglatin", action="store_true", help="atinLay")
+ speak_parser.add_argument("-s", "--shout", action="store_true", help="N00B EMULATION MODE")
+ speak_parser.add_argument("-r", "--repeat", type=int, help="output [n] times")
+ speak_parser.add_argument("words", nargs="+", help="words to say")
@cmd2.with_argparser(speak_parser)
def do_speak(self, args):
@@ -181,17 +182,19 @@ class FirstApp(cmd2.Cmd):
words = []
for word in args.words:
if args.piglatin:
- word = '%s%say' % (word[1:], word[0])
+ word = "%s%say" % (word[1:], word[0])
if args.shout:
word = word.upper()
words.append(word)
repetitions = args.repeat or 1
for _ in range(min(repetitions, self.maxrepeats)):
# .poutput handles newlines, and accommodates output redirection too
- self.poutput(' '.join(words))
+ self.poutput(" ".join(words))
-if __name__ == '__main__':
+
+if __name__ == "__main__":
import sys
+
c = FirstApp()
sys.exit(c.cmdloop())
```
@@ -226,7 +229,7 @@ Even though this is a fully qualified `cmd2` error, the pyscript must check for
perform error checking.:
```py
-app('speak')
+app("speak")
print("Working")
```
@@ -238,7 +241,7 @@ You should notice that no error message is printed. Let's utilize the `CommandRe
inspect the actual returned data.:
```py
-result = app('speak')
+result = app("speak")
print(result)
```
@@ -248,7 +251,7 @@ print(result)
Now we can see that there has been an error. Let's rewrite the script to perform error checking.:
```py
-result = app('speak')
+result = app("speak")
if not result:
print(result.stderr)
@@ -262,7 +265,7 @@ In Python development, it is good practice to fail fast after user input.:
```py
import sys
-result = app('speak TRUTH!!')
+result = app("speak TRUTH!!")
if not result:
print("Something went wrong")
@@ -280,8 +283,8 @@ the `CommandResult`:
```py
import sys
-#Syntax error
-result = app('speak TRUTH!!!')
+# Syntax error
+result = app("speak TRUTH!!!")
if not result:
print("Something went wrong")
sys.exit()
@@ -317,8 +320,8 @@ In the following command example we return a list containing directory elements.
```py
dir_parser = cmd2.Cmd2ArgumentParser()
-dir_parser.add_argument('-l', '--long', action='store_true',
- help="display in long format with one item per line")
+dir_parser.add_argument("-l", "--long", action="store_true", help="display in long format with one item per line")
+
@cmd2.with_argparser(dir_parser, with_unknown_args=True)
def do_dir(self, args, unknown):
@@ -326,15 +329,15 @@ def do_dir(self, args, unknown):
# No arguments for this command
if unknown:
self.perror("dir does not take any positional arguments:")
- self.do_help('dir')
+ self.do_help("dir")
return
# Get the contents as a list
contents = os.listdir(self.cwd)
for f in contents:
- self.poutput(f'{f}')
- self.poutput('')
+ self.poutput(f"{f}")
+ self.poutput("")
self.last_result = contents
```
@@ -342,7 +345,7 @@ def do_dir(self, args, unknown):
The following script retrieves the array contents.:
```py
-result = app('dir')
+result = app("dir")
print(result.data)
```
@@ -373,6 +376,7 @@ app.py:
```py
#!/usr/bin/env python
"""A simple cmd2 application."""
+
import sys
from dataclasses import dataclass
from random import choice, randint
@@ -419,9 +423,7 @@ class FirstApp(cmd2.Cmd):
status = self._start_build(args.name)
self._status_cache[args.name] = status
- self.poutput(
- f"Build {args.name.upper()} successfully started with id : {status.id}"
- )
+ self.poutput(f"Build {args.name.upper()} successfully started with id : {status.id}")
self.last_result = status
status_parser = cmd2.Cmd2ArgumentParser()
@@ -451,11 +453,11 @@ import sys
import time
# start build
-result = app('build tower')
+result = app("build tower")
# If there was an error then exit
if not result:
- print('Build failed')
+ print("Build failed")
sys.exit()
# This is a BuildStatus dataclass object
@@ -465,11 +467,10 @@ print(f"Build {build.name} : {build.status}")
# Poll status
while True:
-
# Perform status check
- result = app('status tower')
+ result = app("status tower")
- #error checking
+ # error checking
if not result:
print("Unable to determine status")
break
@@ -477,7 +478,7 @@ while True:
build_status = result.data
# If the status shows complete then the script is done
- if build_status.status in ['finished', 'canceled']:
+ if build_status.status in ["finished", "canceled"]:
print(f"Build {build.name} has completed")
break
diff --git a/docs/features/settings.md b/docs/features/settings.md
index 568356686..ed663ef45 100644
--- a/docs/features/settings.md
+++ b/docs/features/settings.md
@@ -91,9 +91,11 @@ Here's an example, from
!!! example "examples/environment.py"
+
```py
--8<-- "examples/environment.py"
```
+
If you want to be notified when a setting changes (as we do above), then be sure to supply a method
to the `onchange_cb` parameter of the `cmd2.utils.Settable`. This method will be called after the
diff --git a/docs/features/shortcuts_aliases_macros.md b/docs/features/shortcuts_aliases_macros.md
index cd14dce29..bf88b9fb3 100644
--- a/docs/features/shortcuts_aliases_macros.md
+++ b/docs/features/shortcuts_aliases_macros.md
@@ -19,7 +19,7 @@ format `{'shortcut': 'command_name'}` where you omit `do_` from the command name
class App(Cmd):
def __init__(self):
shortcuts = cmd2.DEFAULT_SHORTCUTS
- shortcuts.update({'*': 'sneeze', '~': 'squirm'})
+ shortcuts.update({"*": "sneeze", "~": "squirm"})
cmd2.Cmd.__init__(self, shortcuts=shortcuts)
```
diff --git a/docs/features/startup_commands.md b/docs/features/startup_commands.md
index fc44d505c..008efde57 100644
--- a/docs/features/startup_commands.md
+++ b/docs/features/startup_commands.md
@@ -32,6 +32,8 @@ application and easily used in automation.
```py
from cmd2 import Cmd
+
+
class App(Cmd):
def __init__(self):
super().__init__(allow_cli_args=False)
@@ -56,7 +58,7 @@ You can execute commands from an initialization script by passing a file path to
```py
class StartupApp(cmd2.Cmd):
def __init__(self):
- cmd2.Cmd.__init__(self, startup_script='.cmd2rc')
+ cmd2.Cmd.__init__(self, startup_script=".cmd2rc")
```
This text file should contain a [Command Script](./scripting.md#command-scripts). See the
@@ -66,7 +68,7 @@ example for a demonstration.
You can silence a startup script's output by setting `silence_startup_script` to True:
```py
-cmd2.Cmd.__init__(self, startup_script='.cmd2rc', silence_startup_script=True)
+cmd2.Cmd.__init__(self, startup_script=".cmd2rc", silence_startup_script=True)
```
!!! warning
diff --git a/docs/mixins/mixin_template.md b/docs/mixins/mixin_template.md
index 10aaa0b06..749717260 100644
--- a/docs/mixins/mixin_template.md
+++ b/docs/mixins/mixin_template.md
@@ -89,7 +89,6 @@ Your mixin can add user visible commands. You do it the same way in a mixin that
```python
class MyMixin:
-
def do_say(self, statement):
"""Simple say command"""
self.poutput(statement)
@@ -108,8 +107,8 @@ class MyMixin:
# code placed here runs before cmd2.Cmd initializes
super().__init__(*args, **kwargs)
# code placed here runs after cmd2.Cmd initializes
- self.mysetting = 'somevalue'
- self.settable.update({'mysetting': 'short help message for mysetting'})
+ self.mysetting = "somevalue"
+ self.settable.update({"mysetting": "short help message for mysetting"})
```
You can also hide settings from the user by removing them from `self.settable`.
@@ -142,7 +141,6 @@ Here's a simple example:
```python
class MyMixin:
-
def __init__(self, *args, **kwargs):
# code placed here runs before cmd2 initializes
super().__init__(*args, **kwargs)
@@ -152,7 +150,7 @@ class MyMixin:
def cmd2_mymixin_postparsing_hook(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
"""Method to be called after parsing user input, but before running the command"""
- self.poutput('in postparsing_hook')
+ self.poutput("in postparsing_hook")
return data
```
diff --git a/docs/testing.md b/docs/testing.md
index 176e9d94b..d7379c19c 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -46,8 +46,8 @@ Another one using [pytest-mock](https://pypi.org/project/pytest-mock) to provide
```py
def test_mocked_methods2(mocker):
- mock_cmdloop = mocker.patch("cmd2.Cmd.cmdloop", autospec=True)
- cli = cmd2.Cmd()
- cli.cmdloop()
- assert mock_cmdloop.call_count == 1
+ mock_cmdloop = mocker.patch("cmd2.Cmd.cmdloop", autospec=True)
+ cli = cmd2.Cmd()
+ cli.cmdloop()
+ assert mock_cmdloop.call_count == 1
```