# Click source notes Repo: `pallets/click` Local checkout: `/home/ubuntu/repos/rodin-sources/click` ## Why this repo is useful - Click is a strong source for CLI API design: stable top-level exports, context-passing conventions, and user-facing exception behavior. - It is especially useful because the implementation ties API design directly to operator experience at the terminal. ## The package root is a curated facade with compatibility shims ### Repeated evidence - `src/click/__init__.py:10-75` re-exports commands, decorators, exceptions, types, and terminal helpers from internal modules. - `src/click/__init__.py:77-124` uses `__getattr__` to keep deprecated compatibility names (`BaseCommand`, `MultiCommand`, `OptionParser`, `__version__`) working while emitting warnings. ### Why it matters Repeated signal: mature libraries often keep the package root stable even while internal layout evolves. Click treats the package root as the user-facing API and places compatibility logic there deliberately. ### Caveat / counterexample Compatibility shims are useful, but they are debt. Click's use of deprecation warnings is the important pattern: keep compatibility explicit and time-bounded rather than silently permanent. ## Command state is passed through context objects, not globals ### Repeated evidence - `docs/complex.md:53-61` explains that callbacks do not receive context unless they opt in, and that `Context.invoke` mediates invocation. - `docs/complex.md:92-99` shows a root command storing application state on `ctx.obj`. - `docs/complex.md:107-113` states directly that `Context.obj` is the place commands are supposed to remember what they need to pass to children. - `src/click/decorators.py:51-93` implements `make_pass_decorator(...)` by searching the linked context chain for the nearest object of the desired type and invoking the callback with it. ### Why it matters Repeated signal: Click favors explicit, nestable context propagation over module globals or hidden singletons. That matters for complex CLIs with subcommands and plugins. ### Caveat / counterexample `docs/complex.md:143-163` points out the interleaved-command problem: plugin layers can replace `ctx.obj`. That is why `make_pass_decorator(...)` exists; plain `pass_obj` is not always enough once commands are nested by third parties. ## Exceptions encode user-visible behavior, not just categorization ### Repeated evidence - `src/click/exceptions.py:35-65` defines `ClickException` with an exit code, cached color behavior, and a `show()` method for terminal rendering. - `src/click/exceptions.py:68-111` defines `UsageError` with a different exit code and help-aware rendering that prints usage plus a "Try '--help'" hint when context is available. - `src/click/exceptions.py:114-118` documents `BadParameter` as a subtype that gains parameter context automatically. ### Why it matters Repeated signal: in CLI libraries, exceptions often need to carry exit semantics and presentation rules, not just messages. Click's hierarchy is built around what the operator should see next. ## Pattern candidates supported by this repo - expose a stable package-level facade over internal modules - use explicit compatibility shims with deprecation warnings - pass CLI state through typed/named context objects rather than globals - design exception types around exit behavior and user guidance