Provides checklist for reviewing Typer CLI command implementations...
Checklist for reviewing Typer CLI command implementations.
src/<cli_app>/commands/app = typer.Typer() and @app.command()@app.command() for each subcommandcommands/__init__.py with add_typer()add_typer(app) without nameadd_typer(app, name="group")Annotated syntax-f, -q)# GOOD:
name: Annotated[str, typer.Argument(help="item name")]
force: Annotated[bool, typer.Option("--force", "-f", help="skip confirmation")] = False
# BAD:
name: str = typer.Argument(..., help="The name of the item.")
display.error()raise typer.Exit(code) after errorsraise typer.Abort() for cancellation# GOOD:
if id < 1:
display.error("ID must be positive")
raise typer.Exit(EXIT_INVALID_INPUT)
# BAD:
if id < 1:
print("Error: ID must be positive")
return
display moduleprint(), typer.echo(), or console.print()# GOOD:
display.success(f"Added '{task.title}'")
# BAD:
print(f"Added '{task.title}'")
--force / -f flagtyper.confirm() with default=False# GOOD:
if not force:
confirm = typer.confirm(f"Delete '{task.title}'?", default=False)
if not confirm:
display.info("Cancelled")
raise typer.Abort()
# BAD: defaults to Yes
confirm = typer.confirm(f"Delete?", default=True)
| Mistake | Fix |
|---|---|
print() |
display.success/error/warning/info() |
| Wrong exit code | 0=success, 1=error, 2=invalid |
Missing --force on delete |
Add force option with default False |
| Confirmation defaults Yes | default=False in typer.confirm() |
| Old Typer syntax | Annotated[type, typer.Argument()] |
Missing app = typer.Typer() |
Each command file needs its own app |
| Not registered | add_typer(app) in commands/__init__.py |
## Review: <command_name>
[OK] Uses Annotated syntax
[OK] Has docstring in imperative mood
[X] Missing --force flag on destructive command
[X] Uses print() instead of display module
[!] Help text could be shorter
### Summary
<brief summary of issues found>
### Suggested Fixes
<code suggestions if needed>