Quickstart Guide
This guide is structured as a tutorial that will walk you through creating command-line applications with typed-clap.
It was adapted from the excellent tutorial for clap-rs using Claude 4.0 Sonnet in Cursor (and some manual cleaning by hand). Most text is lifted verbatim.
Quick Start
You can create an application declaratively with a class and some decorators.
Here is a preview of the type of application you can make:
from pathlib import Path
from typing import Optional
import clap
from clap import ArgAction, arg, long, short
@clap.subcommand
class Test:
"""Does testing things."""
list_flag: bool = arg(short, long="list")
"""Lists test values."""
@clap.command(version="1.0")
class Cli(clap.Parser):
"""A simple to use, efficient, and full-featured Command Line Argument Parser."""
command: Optional[Test]
name: Optional[str] = arg()
"""Optional name to operate on."""
config: Optional[Path] = arg(short, long, value_name="FILE")
"""Sets a custom config file."""
debug: int = arg(short, long, action=ArgAction.Count)
"""Turn debugging information on."""
def main():
cli = Cli.parse()
# You can check the value provided by positional arguments, or option arguments
if cli.name:
print(f"Value for name: {cli.name}")
if cli.config:
print(f"Value for config: {cli.config}")
# You can see how many times a particular flag or argument occurred
# Note, only flags can have multiple occurrences
match cli.debug:
case 0:
print("Debug mode is off")
case 1:
print("Debug mode is kind of on")
case 2:
print("Debug mode is on")
case _:
print("Don't be crazy")
# You can check for the existence of subcommands, and if found use their
# matches just as you would the top level cmd
match cli.command:
case Test(list_flag):
if list_flag:
print("Printing testing lists...")
else:
print("Not printing testing lists...")
case None: ...
# Continued program logic goes here...
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/01_quick.py --help
A simple to use, efficient, and full-featured Command Line Argument Parser
Usage: 01_quick.py [OPTIONS] [NAME] [COMMAND]
Commands:
test Does testing things
Arguments:
[NAME] Optional name to operate on
Options:
-c, --config <FILE> Sets a custom config file
-d, --debug... Turn debugging information on [default: 0]
-h, --help Print help
-V, --version Print versionBy default, the program does nothing:
adityasz@github:typed-clap$ python docs/docs/quickstart/01_quick.py
Debug mode is offBut you can mix and match the various features:
adityasz@github:typed-clap$ python docs/docs/quickstart/01_quick.py -dd test
Debug mode is on
Not printing testing lists...See also:
Configuring the Parser
You use the @clap.command decorator to start building a parser.
import clap
from clap import arg, long
@clap.command(name="MyApp", version="1.0")
class Cli(clap.Parser):
"""Does awesome things."""
two: str = arg(long)
one: str = arg(long)
def main():
cli = Cli.parse()
print(f"two: {cli.two}")
print(f"one: {cli.one}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/02_apps.py --help
Does awesome things
Usage: MyApp --two <TWO> --one <ONE>
Options:
--two <TWO>
--one <ONE>
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/02_apps.py --version
MyApp 1.0Adding Arguments
Arguments are inferred from the fields of your class.
Positionals
By default, class fields define positional arguments:
import clap
from clap import arg
@clap.command(version="1.0")
class Cli(clap.Parser):
name: str = arg()
def main():
cli = Cli.parse()
print(f"name: {cli.name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional.py --help
Usage: 03_03_positional.py <NAME>
Arguments:
<NAME>
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional.py bob
name: bobThe = arg() assignment can be omitted, but then you need to be aware of the
sharp edges.
Note that the default ArgAction is
Set. To accept multiple values, use a list type:
import clap
from clap import arg
@clap.command(version="1.0")
class Cli(clap.Parser):
name: list[str] = arg()
def main():
cli = Cli.parse()
print(f"name: {cli.name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional_mult.py --help
Usage: 03_03_positional_mult.py [<NAME>...]
Arguments:
[<NAME>...]
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional_mult.py
name: []adityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional_mult.py bob
name: ['bob']adityasz@github:typed-clap$ python docs/docs/quickstart/03_03_positional_mult.py bob john
name: ['bob', 'john']Options
You can name your arguments with a flag:
- Intent of the value is clearer
- Order doesn't matter
To specify the flags for an argument, you can use arg() on a
field:
- To automatically generate flags,
shortandlongcan be used:arg(short, long).arg(short=True, long=True)can also be used.
- To specify the flags manually:
arg(short="n", long="name").
Note
arg() takes up to two
positional-only paramters of type
AutoFlag, and short and
long are aliases for
AutoFlag.Short and
AutoFlag.Long. These are used to automatically
generate flags.
It also takes keyword-only arguments
named short and long. These are used for manually specifying the flags.
import clap
from clap import arg, long, short
@clap.command(version="1.0")
class Cli(clap.Parser):
name: str = arg(short, long)
def main():
cli = Cli.parse()
print(f"name: {cli.name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py --help
Usage: 03_02_option.py --name <NAME>
Options:
-n, --name <NAME>
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py --name bob
name: bobadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py --name=bob
name: bobadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py -n bob
name: bobadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py -n=bob
name: bobadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option.py -nbob
name: bobNote that the default ArgAction is
Set. To accept multiple occurrences, override the action
with Append via list:
import clap
from clap import arg, long, short
@clap.command(version="1.0")
class Cli(clap.Parser):
name: list[str] = arg(short, long)
def main():
cli = Cli.parse()
print(f"name: {cli.name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option_mult.py --help
Usage: 03_02_option_mult.py [OPTIONS]
Options:
-n, --name <NAME> [default: []]
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option_mult.py
name: []adityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option_mult.py --name bob
name: ['bob']adityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option_mult.py --name bob --name john
name: ['bob', 'john']adityasz@github:typed-clap$ python docs/docs/quickstart/03_02_option_mult.py --name bob --name=john -n tom -n=chris -nsteve
name: ['bob', 'john', 'tom', 'chris', 'steve']Flags
Flags can also be switches that can be on/off:
import clap
from clap import arg, long, short
@clap.command(version="1.0")
class Cli(clap.Parser):
verbose: bool = arg(short, long)
def main():
cli = Cli.parse()
print(f"verbose: {cli.verbose}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_bool.py --help
Usage: 03_01_flag_bool.py [OPTIONS]
Options:
-v, --verbose
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_bool.py
verbose: Falseadityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_bool.py --verbose
verbose: TrueNote that the default ArgAction for a bool field is
SetTrue. To accept multiple flags, override the
action with Count:
import clap
from clap import ArgAction, arg, long, short
@clap.command(version="1.0")
class Cli(clap.Parser):
verbose: int = arg(short, long, action=ArgAction.Count)
def main():
cli = Cli.parse()
print(f"verbose: {cli.verbose}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_count.py --help
Usage: 03_01_flag_count.py [OPTIONS]
Options:
-v, --verbose... [default: 0]
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_count.py
verbose: 0adityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_count.py --verbose
verbose: 1adityasz@github:typed-clap$ python docs/docs/quickstart/03_01_flag_count.py --verbose --verbose
verbose: 2Optional
By default, arguments are assumed to be required. To make an argument optional,
you can either use PEP 604 annotations, or
wrap the field's type in Optional:
import clap
from clap import arg
@clap.command(version="1.0")
class Cli(clap.Parser):
name: str | None = arg()
# Alternatively, you can use name: Optional[str] = arg()
def main():
cli = Cli.parse()
print(f"name: {cli.name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_06_optional.py --help
Usage: 03_06_optional.py [NAME]
Arguments:
[NAME]
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_06_optional.py
name: Noneadityasz@github:typed-clap$ python docs/docs/quickstart/03_06_optional.py bob
name: bobDefaults
We've previously showed that arguments can be required or optional. When
optional, you work with an Optional and can use or or
provide a default value. Alternatively, you can set default_value.
import clap
from clap import arg
@clap.command(version="1.0")
class Cli(clap.Parser):
port: int = arg(default_value=2020)
def main():
cli = Cli.parse()
print(f"port: {cli.port}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_05_default_values.py --help
Usage: 03_05_default_values.py [PORT]
Arguments:
[PORT] [default: 2020]
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_05_default_values.py
port: 2020adityasz@github:typed-clap$ python docs/docs/quickstart/03_05_default_values.py 22
port: 22Subcommands
Subcommands are created with @clap.subcommand and added via
a type annotation to a field that will contain the parsed result. If there are
multiple subcommands, use Union or
PEP 604 annotations. Each instance of a
subcommand can have its own version, author(s), arguments, and even its own
subcommands.
import clap
from clap import arg
@clap.subcommand
class Add:
"""Adds files to myapp."""
name: str = arg()
@clap.subcommand
class Remove:
"""Remove files from myapp."""
name: str = arg()
@clap.command(version="1.0", propagate_version=True)
class Cli(clap.Parser):
command: Add | Remove
# Alternatively, you can write command: Union[Add, Remove]
quiet: bool = arg(short=True, long=True)
def main():
cli = Cli.parse()
# You can check for the existence of subcommands, and if found use their
# matches just as you would the top level cmd
match cli.command:
case Add(name):
if not cli.quiet:
print(f"'myapp add' was used, name is: {name}")
case Remove(name):
if not cli.quiet:
print(f"'myapp remove' was used, name is: {name}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/03_04_subcommands.py --help
Usage: 03_04_subcommands.py [OPTIONS] <COMMAND>
Commands:
add Adds files to myapp
remove Remove files from myapp
Options:
-q, --quiet
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_04_subcommands.py add --help
Adds files to myapp
Usage: 03_04_subcommands.py [OPTIONS] add <NAME>
Arguments:
<NAME>
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/03_04_subcommands.py add bob
'myapp add' was used, name is: bobTo make a subcommand optional, add a | None or wrap it in an Optional (e.g.
command: Optional[Add]).
Note
Due to type checking limitations, the subcommand needs to be the first field in the class even though it is specified after all other arguments in the command-line, unless you assign an object of a compatible type to it: See sharp edges below.
Since we specified propagate_version=True, the --version flag is available
in all subcommands:
adityasz@github:typed-clap$ python docs/docs/quickstart/03_04_subcommands.py --version
03_04_subcommands.py 1.0adityasz@github:typed-clap$ python docs/docs/quickstart/03_04_subcommands.py add --version
add 1.0Validation
An appropriate default parser/validator will be selected for the field's type.
Enumerated values
For arguments with specific values you want to test for, you can use Python's
Enum. This allows you to specify the valid values for that argument. If the
user does not use one of those specific values, they will receive a graceful
exit with error message informing them of the mistake, and what the possible
valid values are.
from enum import Enum, auto
import clap
from clap import arg
class Mode(Enum):
"""TODO: Help strings are not yet printed for enum values in the long help output.
See TODOs in README.md.
"""
Fast = auto()
"""Run swiftly."""
Slow = auto()
"""Crawl slowly but steadily.
This paragraph is ignored because there is no long help text for possible values.
"""
@clap.command(version="1.0")
class Cli(clap.Parser):
mode: Mode = arg()
"""What mode to run the program in."""
def main():
cli = Cli.parse()
match cli.mode:
case Mode.Fast:
print("Hare")
case Mode.Slow:
print("Tortoise")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/04_01_enum.py --help
Usage: 04_01_enum.py <MODE>
Arguments:
<MODE>
What mode to run the program in
Possible values:
- fast: Run swiftly
- slow: Crawl slowly but steadily
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/04_01_enum.py -h
Usage: 04_01_enum.py <MODE>
Arguments:
<MODE> What mode to run the program in [possible values: fast, slow]
Options:
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/04_01_enum.py fast
Hareadityasz@github:typed-clap$ python docs/docs/quickstart/04_01_enum.py slow
TortoiseArgument Relations
Note
Advanced argument relations and dependencies like requires and
conflicts_with are not yet implemented. You can use Group
for basic grouping and mutual exclusion.
from typing import Optional
import clap
from clap import arg, long
@clap.group(required=True, multiple=False)
class Vers:
set_ver: Optional[str] = arg(long, value_name="VER")
"""Set version manually."""
major: bool = arg(long)
"""Auto inc major."""
minor: bool = arg(long)
"""Auto inc minor."""
patch: bool = arg(long)
"""Auto inc patch."""
@clap.command
class Cli(clap.Parser):
vers: Vers
def main():
cli = Cli.parse()
# Let's assume the old version 1.2.3
major = 1
minor = 2
patch = 3
vers = cli.vers
version: str
# See if --set_ver was used to set the version manually
if vers.set_ver:
version = vers.set_ver
else:
# Increment the one requested (in a real program, we'd reset the lower numbers)
maj, min, pat = vers.major, vers.minor, vers.patch
match maj, min, pat:
case True, _, _: major += 1
case _, True, _: minor += 1
case _, _, True: patch += 1
case _: raise AssertionError
version = f"{major}.{minor}.{patch}"
print(f"Version: {version}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/04_02_groups.py --help
Usage: 04_02_groups.py [OPTIONS] <--set-ver <VER> | --major | --minor | --patch>
Options:
-h, --help Print help
--set-ver <VER> Set version manually
--major Auto inc major
--minor Auto inc minor
--patch Auto inc patchadityasz@github:typed-clap$ python docs/docs/quickstart/04_02_groups.py --major
Version: 2.2.3adityasz@github:typed-clap$ python docs/docs/quickstart/04_02_groups.py --set-ver 1.2.5
Version: 1.2.5adityasz@github:typed-clap$ python docs/docs/quickstart/04_02_groups.py --major --minor
usage: 04_02_groups.py [OPTIONS] <--set-ver <VER> | --major | --minor | --patch>
04_02_groups.py: error: argument --minor: not allowed with argument --majorCustom Validation
As a last resort, you can create custom validation logic in your application after parsing:
import sys
from typing import Optional
import clap
from clap import arg, long, short
@clap.command(version="1.0")
class Cli(clap.Parser):
input_file: Optional[str] = arg()
"""Some regular input."""
set_ver: Optional[str] = arg(long, value_name="VER")
"""Set version manually."""
major: bool = arg(long)
"""Auto inc major."""
minor: bool = arg(long)
"""Auto inc minor."""
patch: bool = arg(long)
"""Auto inc patch."""
spec_in: Optional[str] = arg(long)
"""Some special input argument."""
config: Optional[str] = arg(short)
def main():
cli = Cli.parse()
# Let's assume the old version 1.2.3
major = 1
minor = 2
patch = 3
# See if --set-ver was used to set the version manually
if cli.set_ver is not None:
if cli.major or cli.minor or cli.patch:
print("error: Can't do relative and absolute version change", file=sys.stderr)
sys.exit(1)
version = cli.set_ver
else:
# Increment the one requested (in a real program, we'd reset the lower numbers)
flags_set = [cli.major, cli.minor, cli.patch]
if sum(flags_set) != 1:
print("error: Can only modify one version field", file=sys.stderr)
sys.exit(1)
if cli.major:
major += 1
elif cli.minor:
minor += 1
elif cli.patch:
patch += 1
else:
print(
"error: Must specify one of --set-ver, --major, --minor, or --patch",
file=sys.stderr,
)
sys.exit(1)
version = f"{major}.{minor}.{patch}"
print(f"Version: {version}")
# Check for usage of -c
if cli.config is not None:
input_file = cli.input_file or cli.spec_in
if input_file is None:
print(
"error: INPUT_FILE or --spec-in is required when using --config", file=sys.stderr
)
sys.exit(1)
print(f"Doing work using input {input_file} and config {cli.config}")
if __name__ == "__main__":
main()
adityasz@github:typed-clap$ python docs/docs/quickstart/04_04_custom.py --help
Usage: 04_04_custom.py [OPTIONS] [INPUT_FILE]
Arguments:
[INPUT_FILE] Some regular input
Options:
--set-ver <VER> Set version manually
--major Auto inc major
--minor Auto inc minor
--patch Auto inc patch
--spec-in <SPEC_IN> Some special input argument
-c <CONFIG>
-h, --help Print help
-V, --version Print versionadityasz@github:typed-clap$ python docs/docs/quickstart/04_04_custom.py --major
Version: 2.2.3adityasz@github:typed-clap$ python docs/docs/quickstart/04_04_custom.py --major -c config.toml --spec-in input.txt
Version: 2.2.3
Doing work using input input.txt and config config.tomlDocstrings
import clap
@clap.command
class Cli(clap.Parser):
"""This is the short about (without the trailing period).
Any subsequent paragraphs are ignored in the short about. The long about
contains the entire docstring.
"""
input: str = arg()
"""Help messages are generated in a similar way.
Ellipsis are kept in the short help...
Paragraphs are separated by at least two newlines.
"""
Docstrings are processed just like
clap-rs.
Help Output
See ArgAction.Help,
ArgAction.HelpLong, and
ArgAction.HelpShort.
A custom template can be used, and styles can be customized
using Styles.
Here's the help output for
examples/typst.py:
adityasz@github:typed-clap$ python examples/typst.py --help
Usage: typst [OPTIONS] <COMMAND>
Commands:
watch Watches an input file and recompiles on changes [aliases: w]
init Initializes a new project from a template
Options:
--cert <CERT>
Path to a custom CA certificate to use when making network requests
--color <COLOR>
Whether to use color. When set to `auto` if the terminal to supports it
Possible values:
- auto: Enables colored output only when the output is going to a terminal or TTY
- always: Enables colored output regardless of whether or not the output is going to a
terminal/TTY
- never: Disables colored output no matter if the output is going to a terminal/TTY, or
not
[default: auto]
-h, --help
Print helpadityasz@github:typed-clap$ python examples/typst.py watch -h
Watches an input file and recompiles on changes
Usage: typst [OPTIONS] watch [OPTIONS] <INPUT> [OUTPUT]
Arguments:
<INPUT> Path to input Typst file. Use `-` to read input from stdin
[OUTPUT] Path to output file (PDF, PNG, SVG, or HTML). Use `-` to write output to stdout
Options:
-f, --format <FORMAT> The format of the output file, inferred from the extension by default
[possible values: pdf, png, svg, html]
--ignore-system-fonts Ensures system fonts won't be searched, unless explicitly included via
`--font-path`
-j, --jobs <JOBS> Number of parallel jobs spawned during compilation. Defaults to number
of CPUs
-h, --help Print helpadityasz@github:typed-clap$ python examples/typst.py watch --help
Watches an input file and recompiles on changes
Usage: typst [OPTIONS] watch [OPTIONS] <INPUT> [OUTPUT]
Arguments:
<INPUT>
Path to input Typst file. Use `-` to read input from stdin
[OUTPUT]
Path to output file (PDF, PNG, SVG, or HTML). Use `-` to write output to stdout.
For output formats emitting one file per page (PNG & SVG), a page number template must be
present if the source document renders to multiple pages. Use `{p}` for page numbers,
`{0p}` for zero padded page numbers and `{t}` for page count. For example,
`page-{0p}-of-{t}.png` creates `page-01-of-10.png`, `page-02-of-10.png`, and so on.
Options:
-f, --format <FORMAT> The format of the output file, inferred from the extension by default
[possible values: pdf, png, svg, html]
--ignore-system-fonts Ensures system fonts won't be searched, unless explicitly included via
`--font-path`
-j, --jobs <JOBS> Number of parallel jobs spawned during compilation. Defaults to number
of CPUs
-h, --help Print helpSharp edges
The decorators @clap.command, @clap.group, and
@clap.subcommand are decorated with
@dataclass_transform to tell type checkers that
they provide dataclass-like functionality (for
example, pattern matching with positionals in match-case).
This also brings some dataclass limitations: If fields without default values are present after fields with default values, type checkers will complain. There are no runtime implications, but to satisfy type checkers, the following (reasonable) workarounds can be used:
-
For positionals where you don't need to modify the default behavior, you can simply assign
arg()if there are fields with default values above, even though the runtime behavior does not change. In the examples above, I always did this, even when it was not required, because it makes the intent clearer, especially when the type is a custom class likeFoo:foo: Foomay be an argument group, a subcommand, or an argument, whilefoo: Foo = arg()can only be an argument. -
If a field that contains the subcommand, make it the first field. (The order only matters for positionals; the subcommand is always parsed after all the positionals and options.)
While I would have preferred a solution where it is at the bottom, I do not want to add a dummy function returning
Anyto the API. There exist workarounds, though: If the subcommand is optional, you can assignNoneto it. Alternatively, if you have something likecommand: A | B | C, you can assign an object of any one of these types to it:command: A | B | C = A(). The value is ignored by the library. Note that if the subcommand classAhas a field without a default value (e.g.,num: int, where you do not want to modify any attributes), you will have to assign a default to it (e.g.,num: int = arg()). -
For argument groups, you can call the constructor without any arguments and assign that, e.g.:
Argument groups are generally used for options. However, if an argument group has a positional argument without aninput_opts: InputOpts = InputOpts()= arg()(i.e., you want the default properties), the type checker will complain since that field does not have a default value and must be initialized in the constructor (since it cannot see that a dummy__init__is injected at runtime that will make it possible). So, you can just assign= arg()to it, just like in the first point above.
Before (works at runtime, but static type checkers do not like it):
@clap.subcommand
class FooA:
foo_a: int
@clap.subcommand
class FooB:
foo_b: int
@clap.group
class Stuff:
foo_c: int
foo_d: bool = arg(long)
@clap.command
class Cli(clap.Parser):
foo_e: int = arg(value_name="N")
foo_f: int
more: Stuff
command: FooA | FooB
After:
@clap.subcommand
class FooA:
foo_a: int
@clap.subcommand
class FooB:
foo_b: int
@clap.group
class Stuff:
foo_c: int = arg()
foo_d: bool = arg(long)
@clap.command
class Cli(clap.Parser):
command: FooA | FooB
foo_e: int = arg(value_name="N")
foo_f: int = arg()
more: Stuff = Stuff()
The changes are very minimal, and only make the code clearer:
@clap.subcommand
class FooA:
foo_a: int
@clap.subcommand
class FooB:
foo_b: int
@clap.group
class Stuff:
- foo_c: int
+ foo_c: int = arg()
foo_d: bool = arg(long)
@clap.command
class Cli(clap.Parser):
+ command: FooA | FooB
foo_e: int = arg(value_name="N")
- foo_f: int
+ foo_f: int = arg()
- more: Stuff
+ more: Stuff = Stuff()
- command: FooA | FooB
See also:
- API Reference for complete documentation.
- Examples for application-focused examples.