Skip to content

Commit e9f3210

Browse files
committed
Merge branch 'main' into ap_command_spec
2 parents 34d5f3d + 31d0461 commit e9f3210

36 files changed

Lines changed: 6935 additions & 88 deletions

.github/workflows/codeql-analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232

3333
steps:
3434
- name: Checkout repository
35-
uses: actions/checkout@v6.0.2
35+
uses: actions/checkout@v6.0.3
3636
with:
3737
# We must fetch at least the immediate parents so that if this is
3838
# a pull request then we can checkout the head.

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- name: Check out
20-
uses: actions/checkout@v6.0.2
20+
uses: actions/checkout@v6.0.3
2121
with:
2222
fetch-depth: 0 # Needed for setuptools_scm to work correctly
2323

.github/workflows/quality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Check out
18-
uses: actions/checkout@v6.0.2
18+
uses: actions/checkout@v6.0.3
1919
with:
2020
fetch-depth: 0 # Needed for setuptools_scm to work correctly
2121

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
shell: bash
2222
steps:
2323
- name: Check out
24-
uses: actions/checkout@v6.0.2
24+
uses: actions/checkout@v6.0.3
2525
with:
2626
fetch-depth: 0 # Needed for setuptools_scm to work correctly
2727
- name: Install uv

.github/workflows/typecheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
shell: bash
2323
steps:
2424
- name: Check out
25-
uses: actions/checkout@v6.0.2
25+
uses: actions/checkout@v6.0.3
2626
with:
2727
fetch-depth: 0 # Needed for setuptools_scm to work correctly
2828

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repos:
1414
- id: trailing-whitespace
1515

1616
- repo: https://github.com/astral-sh/ruff-pre-commit
17-
rev: "v0.15.13"
17+
rev: "v0.15.15"
1818
hooks:
1919
- id: ruff-format
2020
args: [--config=ruff.toml]
@@ -30,7 +30,7 @@ repos:
3030
- prettier-plugin-toml@2.0.6
3131

3232
- repo: https://github.com/crate-ci/typos
33-
rev: v1.46.1
33+
rev: v1.47.0
3434
hooks:
3535
- id: typos
3636
exclude: |

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## 4.0.0 (TBD 2026)
1+
## 4.0.0 (June TBD, 2026)
22

33
### Summary
44

@@ -171,6 +171,16 @@ prompt is displayed.
171171
is enabled.
172172
- `alias` and `macro` subcommands for `create` and `delete` now output their non-essential
173173
success case output using `pfeedback`
174+
- Experimental features
175+
- New `@with_annotated` decorator, a type-hint-driven alternative to `@with_argparse` that
176+
builds the parser automatically from a command's signature (positional/option inference,
177+
enum/literal/path/collection handling, subcommands, groups, mutex). See the
178+
[annotated_example.py](https://github.com/python-cmd2/cmd2/blob/main/examples/annotated_example.py)
179+
example for demonstration of usage.
180+
- This feature allows declaring `cmd2` command parameters using type hints using syntax
181+
essentially identical to that used by [Typer](https://typer.tiangolo.com/)
182+
- You use declarative syntax to define the arguments a command takes and the
183+
`@with_annotated` decorator builds an `argparse` parser for you
174184

175185
## 3.5.1 (April 24, 2026)
176186

cmd2/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
rich_utils,
1212
string_utils,
1313
)
14+
from .annotated import with_annotated
1415
from .argparse_completer import set_default_ap_completer_type
1516
from .argparse_utils import (
1617
Cmd2ArgumentParser,
@@ -88,6 +89,7 @@
8889
"CompletionItem",
8990
"Completions",
9091
# Decorators
92+
"with_annotated",
9193
"with_argument_list",
9294
"with_argparser",
9395
"with_category",

cmd2/annotated.py

Lines changed: 2323 additions & 0 deletions
Large diffs are not rendered by default.

cmd2/argparse_utils.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
Example::
1717
1818
# -f argument expects at least 3 values
19-
parser.add_argument('-f', nargs=(3,))
19+
parser.add_argument("-f", nargs=(3,))
2020
2121
# -f argument expects 3 to 5 values
22-
parser.add_argument('-f', nargs=(3, 5))
22+
parser.add_argument("-f", nargs=(3, 5))
2323
2424
2525
**Completion**
@@ -38,8 +38,8 @@
3838
3939
Example::
4040
41-
my_list = ['An Option', 'SomeOtherOption']
42-
parser.add_argument('-o', '--options', choices=my_list)
41+
my_list = ["An Option", "SomeOtherOption"]
42+
parser.add_argument("-o", "--options", choices=my_list)
4343
4444
``choices_provider`` - pass a function that returns a Choices object. This is good in
4545
cases where the choices are dynamically generated when the user hits tab.
@@ -50,6 +50,7 @@ def my_choices_provider(self) -> Choices:
5050
...
5151
return my_choices
5252
53+
5354
parser.add_argument("arg", choices_provider=my_choices_provider)
5455
5556
``completer`` - pass a function that does custom completion and returns a Completions object.
@@ -60,17 +61,16 @@ def my_choices_provider(self) -> Choices:
6061
Example::
6162
6263
# This adds file-path completion to an argument
63-
parser.add_argument('-o', '--options', completer=cmd2.Cmd.path_complete)
64+
parser.add_argument("-o", "--options", completer=cmd2.Cmd.path_complete)
6465
6566
You can use functools.partial() to prepopulate values of the underlying
6667
choices and completer functions/methods.
6768
6869
Example::
6970
7071
# This says to call path_complete with a preset value for its path_filter argument
71-
dir_completer = functools.partial(path_complete,
72-
path_filter=lambda path: os.path.isdir(path))
73-
parser.add_argument('-o', '--options', completer=dir_completer)
72+
dir_completer = functools.partial(path_complete, path_filter=lambda path: os.path.isdir(path))
73+
parser.add_argument("-o", "--options", completer=dir_completer)
7474
7575
For ``choices_provider`` and ``completer``, do not set them to a bound method. This
7676
is because ArgparseCompleter passes the `self` argument explicitly to these

0 commit comments

Comments
 (0)