typed-clap1
A declarative and type-safe argument parser for Python, inspired by clap-rs.
Installation 
- Using uv:
uv add typed-clap - Using pip:
pip install typed-clap
Example
import clap
from clap import arg, long, short
from pathlib import Path
@clap.command
class Cli(clap.Parser):
"""A tiny script."""
input: Path = arg(value_name="PATH")
"""Path to the input file."""
verbose: bool = arg(short, long)
"""Enable verbose output."""
cli = Cli.parse()
if cli.verbose:
print(f"Reading {cli.input}...")
See /examples for more examples.
Features
-
Help generation from docstrings
Use the same string for the help output as well as documentation in the IDE.
-
@clap.subcommand class Add: file: Path @clap.subcommand class List: directory: Path @clap.command class Cli(clap.Parser): command: Add | List cli = Cli.parse() match cli.command: case Add(file): print(f"Adding {file}...") case List(directory): print(f"Listing {directory}...")
-
@clap.group(required=True, multiple=False) class InputOptions: """Only one of these can be provided. This can be shared between multiple parsers in different scripts!""" dpi: Optional[int] = arg(long) resolution: Optional[tuple[int, int]] = arg(long, value_name="PX") @clap.command class Cli(clap.Parser): input_options: InputOptions cli = Cli.parse() print(cli.input_options.dpi or cli.input_options.resolution)
-
Separate short and long help with
-hand--help. See example output here.
Docs
Documentation along with the
quickstart guide
can be found on the docs website
built from /docs.
Motivation
argparse doesn't work with static analysis tools.
Static analysis is important to prevent errors like these:
import argparse
from pathlib import Path
import torch
parser = argparse.ArgumentParser()
# 50 lines of other arguments...
parser.add_argument("--data", type=Path)
parser.add_argument("--some-number", type=Path) # copy-paste error in type
# 30 lines of other arguments...
args = parser.parse_args()
# 500 lines of code...
c = 1 / args.some_number # some_number was accidentally set to be Path
# ~~^~~~~~~~~~~~~~~~~~
Once that error is fixed and the script is re-run:
# 1500 lines of code...
torch.save(agi, args.data_dir / "agi.pt") # this attribute does not exist
# ~~~~~~~~~^^^^
These errors are detected right when you typed them if you use this library and
a type checker like pyright. (A dry run is obviously still recommended before
starting long training runs. E.g., this library will not see if args.data_dir
exists on disk.)
Also, using subcommands with argparse is error-prone because argparse returns
a flat namespace, overwriting global arguments with subcommand arguments. This
should be written in bold all over the argparse docs but it isn't. The
workaround is to manually set dest for each argument, which is a tedious and
error-prone process.
Supported type checkers
typed-clap is successfully type checked in CI by:
Contributing
PRs that fix bugs, add features from clap-rs, or complete the following TODOs are welcome. For adding other features, please create a discussion before creating a PR. Thank you!
TODO (v1.0)
- Better diagnostics (source range highlighting etc.) for incorrect parsers.
- Parse arguments manually instead of using
argparse. This will improve error messages for invalid arguments.
Future work (beyond v1.0)
- Add support for custom value parsers, validation,
conflicts_with, etc. - Generate shell completions.
- Add a clap-like builder API to add arguments procedurally (after defining some arguments in a class), which can be used together with the declarative API.
- Find or build out the python equivalent of
color_print::cstr!and support styled help strings that wrap properly and are formatted depending on output file.
Acknowledgements
clap-rs. Most docstrings are lifted verbatim.
-
Because the names clap{,-py,-python} were already taken on PyPI :-( ↩
-
ty is not a part of the CI because it gives some false positives in the completely standard internal code since ty is not complete and still a WIP. It does not have any issues with the APIs of this library or their usage, though. ↩
Metadata
Release files for typed-clap 0.11.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| typed_clap-0.11.1.tar.gz | 23.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typed_clap-0.11.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.3 kB
Release files / typed_clap-0.11.1.tar.gz
| Download URL | typed_clap-0.11.1.tar.gz |
|---|---|
| Size | 23.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9e91ea7396d7b0e13e4ede1e382f9948502e9fe215d36c09e73939fd5e1331b
|
|
BLAKE2b-256 checksum How to use checksums |
b629aaa42495a529928db46e9394d1bb195fbf6c0084e965f3558758baee2577
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / typed_clap-0.11.1-py3-none-any.whl
| Download URL | typed_clap-0.11.1-py3-none-any.whl |
|---|---|
| Size | 26.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e4985777e0492a59da6b05318ed7f3c06b711fdf2378e43e8897d370f6764418
|
|
BLAKE2b-256 checksum How to use checksums |
05dfecb643841e36f28fd333632be9a7dae67e8c66e71541cc9f7a630089d137
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|