Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,12 @@ The one plugin we consider essential for PyCharm is
[RyeCharm](https://plugins.jetbrains.com/plugin/25230-ryecharm). `RyeCharm` is an all-in-one PyCharm
plugin for [Astral](https://astral.sh/)-backed Python tools: [uv](https://github.com/astral-sh/uv),
[Ruff](https://github.com/astral-sh/ruff), and [ty](https://github.com/astral-sh/ty). NOTE: `ty`
support is provisional as that new type checker is in early alpha developement.
support is provisional as that new type checker is in early alpha development.

#### VSCode Settings

While **VSCode** is a phenomenal IDE for developing in Python, the out-of-the-box experience leaves
a lot to be desired. You will need to install a number of extenstions and tweak the default
a lot to be desired. You will need to install a number of extensions and tweak the default
configuration for many of them in order to get an optimal developer experience.

Recommended VSCode extensions:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ jobs:
python-version: "3.14"
- name: Install the project
run: uv sync --group quality
- name: Run pre-commit
run: uv run pre-commit run -a --show-diff-on-failure
- name: Run prek
run: uv run prek run -a --show-diff-on-failure
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ repos:
rev: "v6.0.0"
hooks:
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-symlinks
- id: check-toml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
Expand All @@ -23,3 +29,13 @@ repos:
additional_dependencies:
- prettier@3.8.1
- prettier-plugin-toml@2.0.6

- repo: https://github.com/crate-ci/typos
rev: v1.44.0
hooks:
- id: typos
exclude: |
(?x)^(
ruff.toml|
tests/.*
)$
5 changes: 5 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[default.extend-words]
EXPLIoT = "EXPLIoT"
Counterfit = "Counterfit"
expliot = "expliot"
counterfit = "counterfit"
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ install: ## Install the virtual environment with dependencies
@echo "🚀 Creating uv Python virtual environment"
@uv python install 3.14
@uv sync --python=3.14
@echo "🚀 Installing Git pre-commit hooks locally"
@uv run pre-commit install
@echo "🚀 Installing Git prek hooks locally"
@uv run prek install -f
@echo "🚀 Installing Prettier using npm"
@npm install -q --no-fund --include=dev

.PHONY: check
check: ## Run code quality tools.
@echo "🚀 Checking lock file consistency with 'pyproject.toml'"
@uv lock --locked
@echo "🚀 Linting code and documentation: Running pre-commit"
@uv run pre-commit run -a
@echo "🚀 Auto-formatting/Linting code and documentation: Running prek"
@uv run prek run -a
@echo "🚀 Static type checking: Running mypy"
@uv run mypy

Expand Down
2 changes: 1 addition & 1 deletion README.md
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ examples.
- [cmd2 example applications](https://github.com/python-cmd2/cmd2/tree/main/examples)
- Basic cmd2 examples to demonstrate how to use various features
- [Advanced Examples](https://github.com/jayrod/cmd2-example-apps)
- More complex examples that demonstrate more featuers about how to put together a complete
- More complex examples that demonstrate more features about how to put together a complete
application
- [Cookiecutter](https://github.com/cookiecutter/cookiecutter) Templates from community
- Basic cookiecutter template for cmd2 application :
Expand Down
4 changes: 2 additions & 2 deletions cmd2/argparse_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,14 @@ def __init__(

@property
def choices_provider(self) -> ChoicesProviderUnbound[CmdOrSet]:
"""Retreive the internal choices_provider function."""
"""Retrieve the internal choices_provider function."""
if self.is_completer:
raise AttributeError("This instance is configured as a completer, not a choices_provider")
return cast(ChoicesProviderUnbound[CmdOrSet], self.to_call)

@property
def completer(self) -> CompleterUnbound[CmdOrSet]:
"""Retreive the internal completer function."""
"""Retrieve the internal completer function."""
if not self.is_completer:
raise AttributeError("This instance is configured as a choices_provider, not a completer")
return cast(CompleterUnbound[CmdOrSet], self.to_call)
Expand Down
6 changes: 3 additions & 3 deletions cmd2/cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def remove(self, command_method: CommandFunc) -> None:

@dataclass(kw_only=True)
class AsyncAlert:
"""Contents of an asynchonous alert which display while user is at prompt.
"""Contents of an asynchronous alert which display while user is at prompt.

:param msg: an optional message to be printed above the prompt.
:param prompt: an optional string to dynamically replace the current prompt.
Expand Down Expand Up @@ -608,7 +608,7 @@ def __init__(
# Command parsers for this Cmd instance.
self._command_parsers: _CommandParsers = _CommandParsers(self)

# Members related to printing asychronous alerts
# Members related to printing asynchronous alerts
self._alert_queue: deque[AsyncAlert] = deque()
self._alert_condition = threading.Condition()
self._alert_allowed = False
Expand Down Expand Up @@ -3508,7 +3508,7 @@ def _pre_prompt() -> None:
self._alert_allowed = False

def _cmdloop(self) -> None:
"""Repeatedly issue a prompt, accept input, parse it, and dispatch to apporpriate commands.
"""Repeatedly issue a prompt, accept input, parse it, and dispatch to appropriate commands.

Parse an initial prefix off the received input and dispatch to action methods, passing them
the remainder of the line as argument.
Expand Down
2 changes: 1 addition & 1 deletion docs/doc_conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ or [The Markdown Guide](https://www.markdownguide.org/) for a more complete refe

Code blocks can be created in two ways:

- Indent the block - this will show as a monospace code block, but won't include highighting
- Indent the block - this will show as a monospace code block, but won't include highlighting
- use the triple backticks followed by the code language, e.g. `python` and close with triple
backticks

Expand Down
4 changes: 2 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ each:
- Demonstrates usage of `@with_default_category` decorator to group and categorize commands and
`CommandSet` use
- [dynamic_commands.py](https://github.com/python-cmd2/cmd2/blob/main/examples/dynamic_commands.py)
- Shows how `do_*` commands can be dynamically created programatically at runtime
- Shows how `do_*` commands can be dynamically created programmatically at runtime
- [environment.py](https://github.com/python-cmd2/cmd2/blob/main/examples/environment.py)
- Shows how to create custom `cmd2.Settable` parameters which serve as internal environment
variables
Expand All @@ -63,7 +63,7 @@ each:
- Shows how to use various `cmd2` application lifecycle hooks
- [migrating.py](https://github.com/python-cmd2/cmd2/blob/main/examples/migrating.py)
- A simple `cmd` application that you can migrate to `cmd2` by changing one line
- [modular_commands.py](https://github.com/python-cmd2/cmd2/blob/main/examples/modular_commands.py)
- [modular_commandsets.py](https://github.com/python-cmd2/cmd2/blob/main/examples/modular_commandsets.py)
- Complex example demonstrating a variety of methods to load `CommandSets` using a mix of
command decorators
- [paged_output.py](https://github.com/python-cmd2/cmd2/blob/main/examples/paged_output.py)
Expand Down
6 changes: 3 additions & 3 deletions examples/command_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
most commands trivial because the intent is to focus on the CommandSet feature set.

The `AutoLoadCommandSet` is a basic command set which is loaded automatically at application startup and stays loaded until
application exit. Ths is the simplest case of simply modularizing command definitions to different classes and/or files.
application exit. This is the simplest case of simply modularizing command definitions to different classes and/or files.

The `LoadableFruits` and `LoadableVegetables` CommandSets are dynamically loadable and un-loadable at runtime using the `load`
and `unload` commands. This demonstrates the ability to load and unload CommandSets based on application state. Each of these
Expand Down Expand Up @@ -102,7 +102,7 @@ def __init__(self) -> None:

self.register_command_set(AutoLoadCommandSet())

# Store the dyanmic CommandSet classes for ease of loading and unloading
# Store the dynamic CommandSet classes for ease of loading and unloading
self._fruits = LoadableFruits()
self._vegetables = LoadableVegetables()

Expand Down Expand Up @@ -147,7 +147,7 @@ def do_unload(self, ns: argparse.Namespace) -> None:
@with_argparser(cut_parser)
@with_category(COMMANDSET_SUBCOMMAND)
def do_cut(self, ns: argparse.Namespace) -> None:
"""Intended to be used with dyanmically loaded subcommands specifically."""
"""Intended to be used with dynamically loaded subcommands specifically."""
handler = ns.cmd2_handler.get()
if handler is not None:
handler(ns)
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def integer(value_str: str) -> int:


def hexadecimal(value_str: str) -> int:
"""Parse hexidecimal integer, with optional '0x' prefix."""
"""Parse hexadecimal integer, with optional '0x' prefix."""
return int(value_str, base=16)


Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dev = [
"ipython>=8.23",
"mkdocstrings[python]>=1",
"mypy>=1.13",
"pre-commit>=3",
"prek>=0.3.5",
"pytest>=8.1.1",
"pytest-cov>=5",
"pytest-mock>=3.14.1",
Expand All @@ -58,7 +58,7 @@ docs = [
"setuptools_scm>=8",
"zensical>=0.0.17",
]
quality = ["pre-commit>=3"]
quality = ["prek>=0.3.5"]
test = [
"codecov>=2.1",
"coverage>=7.11",
Expand Down
2 changes: 1 addition & 1 deletion ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ mccabe.max-complexity = 49
# Ignore starting a process with a partial executable path (i.e. git)
"scripts/validate_tag.py" = ["S607"]

# Ingore various rulesets in test directories
# Ignore various rulesets in test directories
"{tests}/*.py" = [
"ANN", # Ignore all type annotation rules in test folders
"ARG", # Ignore all unused argument warnings in test folders
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2900,7 +2900,7 @@ def test_macro_usage_with_missing_args(base_app) -> None:
assert "expects at least 2 arguments" in err[0]


def test_macro_usage_with_exta_args(base_app) -> None:
def test_macro_usage_with_extra_args(base_app) -> None:
# Create the macro
out, _err = run_cmd(base_app, 'macro create fake help {1}')
assert out == normalize("Macro 'fake' created")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_commandset.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def do_builtin(self, _) -> None:

# Create a synonym to a command outside of this CommandSet with subcommands.
# This will best test the synonym check in cmd2.Cmd._check_uninstallable() when
# we unresgister this CommandSet.
# we unregister this CommandSet.
do_alias_synonym = cmd2.Cmd.do_alias

cs = SynonymCommandSet("foo")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ def test_get_completions_add_opening_quote_and_return_results(
def test_get_completions_allow_finalization(
self, line, match, quote_char, end_of_line, expected, mock_cmd_app: MockCmd
) -> None:
"""Test that get_completions corectly handles finalizing single matches."""
"""Test that get_completions correctly handles finalizing single matches."""
completer = pt_utils.Cmd2Completer(cast(Any, mock_cmd_app))

# Set up document
Expand Down
Loading