{"id":3881,"library":"argh","title":"Argh: Effortless CLI","description":"Argh is a lightweight Python library that simplifies the creation of command-line interfaces (CLIs) by building on top of the `argparse` module. It allows developers to define CLI commands using plain Python functions, reducing boilerplate code and inferring arguments from function signatures and type annotations. The library is actively maintained, with regular releases, and is currently at version 0.31.3.","status":"active","version":"0.31.3","language":"en","source_language":"en","source_url":"https://github.com/neithere/argh","tags":["cli","command-line","argparse","interface","automation","tooling"],"install":[{"cmd":"pip install argh","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required Python version","package":"python","version":">=3.8"},{"reason":"Built-in standard library module that Argh wraps","package":"argparse","optional":false},{"reason":"Optional dependency for shell tab-completion","package":"argcomplete","optional":true}],"imports":[{"note":"Used for single-command CLI applications.","symbol":"dispatch_command","correct":"from argh import dispatch_command"},{"note":"Used for multi-command CLI applications.","symbol":"dispatch_commands","correct":"from argh import dispatch_commands"},{"note":"The `arg` decorator is directly available from the top-level `argh` package since v0.30.0 for cleaner imports, although older paths might still work for compatibility.","wrong":"from argh.decorators import arg","symbol":"arg","correct":"from argh import arg"}],"quickstart":{"code":"import argh\nimport os\n\ndef verify_paths(paths: list[str], *, verbose: bool = False):\n    \"\"\"Verify that all given paths exist.\"\"\"\n    for path in paths:\n        if verbose:\n            print(f\"Checking {path}...\")\n        if not os.path.exists(path):\n            raise FileNotFoundError(f\"Path does not exist: {path}\")\n    print(\"All paths verified successfully.\")\n\nif __name__ == \"__main__\":\n    # For a single command application, use dispatch_command.\n    # For multiple commands, use argh.dispatch_commands([cmd1, cmd2]).\n    # Note: old_name_mapping_policy=False is often recommended during the transition\n    # for explicit argument mapping, especially with positional arguments having defaults.\n    argh.dispatch_command(verify_paths, old_name_mapping_policy=False)\n","lang":"python","description":"This quickstart demonstrates how to create a simple CLI application with a single command (`verify_paths`) that accepts a list of paths and an optional verbose flag. Argh automatically infers arguments and types from the function signature and annotations. Run the script with `python your_script.py path1.txt path2.csv --verbose`."},"warnings":[{"fix":"Explicitly use `@argh.arg` decorators for arguments where automatic type hint introspection is not desired, or adjust your function signatures to match the desired CLI behavior.","message":"Argh v0.31.0 automatically enables typing hints introspection for functions without `@arg` decorators. This may change behavior if you previously relied on no introspection for such functions, potentially leading to unexpected argument parsing.","severity":"breaking","affected_versions":">=0.31.0"},{"fix":"To retain the old behavior of mapping to an option, explicitly define the argument as keyword-only (e.g., `def func(foo, *, bar=None)`). For complex cases, explicitly specify `old_name_mapping_policy=True` in `dispatch_command` or `dispatch_commands` during the transition, though this will change in future versions.","message":"Argh v0.30.0 introduced a new default policy for mapping function arguments to CLI arguments. Positional arguments with default values now map to positional CLI arguments instead of optional flags (e.g., `def func(foo, bar=None)` maps `bar` as a positional `[bar]` instead of `--bar`).","severity":"breaking","affected_versions":">=0.30.0"},{"fix":"Review affected function signatures and either make the argument keyword-only (e.g., `def func(foo, *, bar=None)`) or explicitly pass `old_name_mapping_policy=True` to `dispatch_command`/`dispatch_commands` if the legacy behavior is intended.","message":"Since v0.30.2, Argh raises `ArgumentNameMappingError` if a non-keyword-only argument has a default value and no explicit name mapping policy is defined. This prevents silent misinterpretation of CLI arguments based on the new policy.","severity":"gotcha","affected_versions":">=0.30.2"},{"fix":"Remove usages of `@expects_obj` and rely on standard function signatures or `@arg` decorators. For help, use the standard `--help` flag instead of `help` as a positional command.","message":"The `@expects_obj` decorator and the `add_help_command` argument in `dispatch()` (which enabled the `help` positional command alias) were deprecated in v0.30.0 and subsequently removed in v0.31.0.","severity":"deprecated","affected_versions":"0.30.0 - 0.30.x"},{"fix":"Upgrade to Argh v0.31.2 or later to ensure correct parsing of `List` and `Optional[List]` type hints.","message":"Earlier versions (prior to v0.31.2) had broken support for type aliases like `typing.List` and `typing.Optional[List]`, leading to incorrect argument parsing for these types.","severity":"gotcha","affected_versions":"<0.31.2"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}