pallets/clickBSD-3-Clause06b2a67Report / request removal

Commands and Groups

Click turns Python callbacks into runnable command-line units and lets those units compose into nested applications. A Command owns parsing and callback execution; a Group adds a registry of child commands and resolves remaining arguments to a child.

This hierarchy exists so a small single-command script and a multi-level CLI use the same invocation model. The shared Context carries parsed values and parent-child state while each command keeps its own parameters.

Sources: src/click/core.py:2048-2114, docs/commands-and-groups.md:164-195, src/click/core.py:366-540

Core concepts

BaseCommand

BaseCommand is a deprecated compatibility name for _BaseCommand, which is a subclass of Command slated for removal.

Sources: src/click/core.py:1692-1696, src/click/init.py:79-88

Command

A Command is the basic CLI unit: it stores a callback and parameters, parses arguments, and invokes the callback when run.

Sources: src/click/core.py:985-1681, src/click/core.py:1061-1103, src/click/core.py:1428-1442

Group

A Group is a command that nests other commands or groups, stores them by exported name, and dispatches to one or more of them.

Sources: src/click/core.py:1699-2159, src/click/core.py:1758-1811, src/click/core.py:2048-2114

MultiCommand

MultiCommand is a deprecated compatibility name for _MultiCommand; the current Group implementation merged with and replaced that base class.

TypeMain responsibilityChild commandsInvocation shape
BaseCommandLegacy compatibility surfaceNot established hereSuperseded by Command
CommandParse parameters and run one callbackNo registry shownOne command callback
GroupRegister and dispatch commandsCommands and groupsOne child, or several in chain mode
MultiCommandLegacy compatibility surfaceReplaced by GroupUse Group for current behavior

The table reflects the class roles and compatibility relationships shown by the core declarations and package exports.

This diagram shows how the decorator API turns functions into registered command objects.

Command registration — How do functions become children of a group?

Evidence

The group decorators create a command or subgroup and immediately register it with add_command; registration uses the command's name unless an explicit name is supplied.

Sources: src/click/core.py:2162-2166, src/click/core.py:1699-2159, src/click/init.py:90-99, src/click/core.py:985-1681, src/click/core.py:1692-1696, src/click/core.py:1849-1888, src/click/core.py:1898-1940, src/click/core.py:1831-1839

How a group dispatches one command

A group keeps registered children in commands, and list_commands exposes their names in sorted order. get_command then maps the command-line name to the corresponding Command, returning None when no match exists.

Parsing separates the first command token from the remaining arguments: Group.parse_args stores the selected token in _protected_args and the rest in args for a normal group. The parent context is then kept active while the group resolves the name, invokes the group callback, creates a child context, and invokes the selected child.

The group callback therefore runs before the selected subcommand callback in the normal path. This is why group-level options belong to the group while subcommand options must appear after the subcommand name.

This sequence shows the normal call order from group resolution to child callback.

Normal group dispatch — How does one command line reach its selected subcommand?

Evidence

Each child receives a new Context linked to its parent, and make_context parses the child's arguments without invoking its callback yet. The child callback is eventually reached through Command.invoke, which delegates callback execution to Context.invoke. Context.invoke fills missing command parameters from defaults, records them in the child context, and calls the callback with the resulting keyword arguments.

If no command remains, a group either fails with “Missing command” or invokes its own callback when invoke_without_command is enabled. By default, no_args_is_help is derived as the opposite of invoke_without_command.

Sources: src/click/core.py:1758-1811, src/click/core.py:1993-1995, src/click/core.py:1987-1991, src/click/core.py:2034-2046, src/click/core.py:2048-2114, docs/commands-and-groups.md:192-205, src/click/core.py:867-873, src/click/core.py:1355-1390, src/click/core.py:1428-1442, src/click/core.py:883-936

How command chaining changes invocation

With chain=False, the group resolves exactly one child and returns that child’s result after processing it. With chain=True, the remaining arguments are treated as a sequence of command segments: the group sets invoked_subcommand to "*", resolves commands repeatedly, creates a context for each one, invokes every child in order, and collects their return values into a list.

The difference matters to callbacks. In a normal group, the group can know the selected subcommand name before its callback runs; in chain mode, it only knows that commands will run, not the complete list, so Context.invoked_subcommand is "*". A registered result_callback receives the final value, or the list of child results for a chained invocation.

Chain mode also changes the accepted structure. The group constructor rejects optional arguments on a chained group, and _check_nested_chain rejects groups nested below a chain group. The documentation additionally records that only the last command may use nargs=-1, and options must precede arguments within each chained command.

The two modes differ in whether dispatch creates one child context or a sequence of child contexts.

Single versus chained dispatch — What changes when chain mode is enabled?

Evidence

The group’s result_callback is the hand-off point for pipelines: chained commands can return values, and the result callback can receive the list after all children finish. The alternative is shared state on a context object, which parent contexts pass onward to children.

Sources: src/click/core.py:2048-2114, src/click/core.py:366-540, src/click/core.py:1699-2159, src/click/core.py:1758-1811, src/click/core.py:83-100, docs/commands.md:165-173, src/click/core.py:1942-1985, docs/commands.md:58-96

How it connects

The decorator layer creates Command and Group objects from functions, so start with The Decorator API when the question is how registration begins.

The Context hierarchy explains parent links, obj propagation, invoked_subcommand, and callback invocation; see Context and Execution.

Command parsing delegates parameter handling to the shared parameter model and underlying parser, which are covered by The Parameter Model and The Low-Level Parser.

Group completion enumerates visible commands through _complete_visible_commands, while Group.shell_complete adds those completions to its results; see Shell Completion.

Sources: src/click/decorators.py:173-188, src/click/decorators.py:293-311, src/click/core.py:366-540, src/click/core.py:883-936, src/click/core.py:1392-1426, src/click/core.py:2142-2159

Key takeaways

  • Command runs one callback; Group is a command registry and dispatcher.
  • BaseCommand/MultiCommand are compatibility names represented by _BaseCommand/_MultiCommand; current code uses Command and Group.
  • Normal groups resolve one child, while chained groups resolve and invoke multiple children in sequence.
  • Group callbacks run before child callbacks, and child contexts preserve parent context relationships.
  • Chain mode uses "*" for invoked_subcommand, collects child results, and forbids nested groups.

Sources: src/click/core.py:985-1681, src/click/core.py:1699-2159, src/click/core.py:1692-1696, src/click/core.py:2162-2166, src/click/core.py:2048-2114, src/click/core.py:867-873, src/click/core.py:83-100

Want this for your repos?

Try Angada AI Wiki