Skip to main content

A declarative and type-safe command-line argument parser.

Project description

typed-clap[^1]

CI

A declarative and type-safe argument parser for Python, inspired by clap-rs.

Installation uv

  • 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.

  • Subcommands

    @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}...")
    
  • Argument groups

    @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 -h and --help. See example output here.

  • Customize help output with templates and styles.

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:

It can also be used with ty[^2].

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.

[^1]: Because the names clap{,-py,-python} were already taken on PyPI :-( [^2]: 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typed_clap-0.11.1.tar.gz (23.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typed_clap-0.11.1-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file typed_clap-0.11.1.tar.gz.

File metadata

  • Download URL: typed_clap-0.11.1.tar.gz
  • Upload date:
  • Size: 23.4 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for typed_clap-0.11.1.tar.gz
Algorithm Hash digest
SHA256 f9e91ea7396d7b0e13e4ede1e382f9948502e9fe215d36c09e73939fd5e1331b
MD5 b093d5d38717d2949c7c60d355952878
BLAKE2b-256 b629aaa42495a529928db46e9394d1bb195fbf6c0084e965f3558758baee2577

See more details on using hashes here.

File details

Details for the file typed_clap-0.11.1-py3-none-any.whl.

File metadata

  • Download URL: typed_clap-0.11.1-py3-none-any.whl
  • Upload date:
  • Size: 26.9 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for typed_clap-0.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e4985777e0492a59da6b05318ed7f3c06b711fdf2378e43e8897d370f6764418
MD5 e9bb4dacb2eab26bde94cb40ea57a997
BLAKE2b-256 05dfecb643841e36f28fd333632be9a7dae67e8c66e71541cc9f7a630089d137

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page