pallets/clickBSD-3-Clause06b2a67Report / request removal

The Low-Level Parser

The low-level parser turns a command-line token list into option values, positional values, and any remaining arguments before Click’s higher-level command and parameter machinery handles them. It is implemented by _OptionParser, an internal parser modeled after optparse but intentionally simpler.

It exists to keep token recognition separate from higher-level concerns such as type conversion and defaults. The parser records syntax and ordering; the higher layer can then interpret the resulting values and parameters.

Sources: src/click/parser.py:224-232

Core concepts

_OptionParser

An option parser owns registered options and positional arguments, then coordinates the complete parse through parse_args. It maintains separate short-option and long-option maps, the recognized option prefixes, and the registered positional arguments.

Sources: src/click/parser.py:224-500, src/click/parser.py:260-263

_ParsingState

Parsing state is the mutable workspace containing parsed option values, leftover positional-looking arguments, remaining input tokens, and the order in which parameters appeared.

Sources: src/click/parser.py:216-221

_Option

An option describes how one or more option spellings map to a destination and action. _Option separates short and long spellings, records prefixes, and knows whether its action consumes a value.

Sources: src/click/parser.py:127-167

_Argument

An argument represents a positional parameter with a destination and an nargs specification. Its process method writes the collected value into parsing state and records the parameter’s position in the input order.

Sources: src/click/parser.py:185-213

How parsing starts and separates token classes

parse_args creates a _ParsingState, processes option-like tokens first, then assigns the remaining tokens to registered positional arguments. It returns the parsed values, leftovers, and parameter order as (values, args, order).

Token flow through the parser — How do command-line tokens become parser results?

Evidence

The option pass removes tokens from state.rargs one at a time. A token equal to -- stops option processing; a token beginning with a recognized prefix is dispatched as an option; otherwise the token is placed in state.largs when interspersed arguments are allowed.

When interspersed arguments are disabled, the first non-option is put back into state.rargs and option processing stops. This supports boundaries such as nested subcommand parsing without consuming later tokens as options.

After option processing, _process_args_for_args combines state.largs and the remaining state.rargs, then calls _unpack_args using each registered argument’s nargs. _unpack_args fills missing positions with UNSET, supports fixed-width groups, and supports one wildcard position that consumes the remainder.

Sources: src/click/parser.py:298-314, src/click/parser.py:327-341, src/click/parser.py:245-249, src/click/parser.py:316-324, src/click/parser.py:51-108

How prefixes and option names are classified

_split_opt classifies an option spelling by examining its first character and whether the first two characters form a repeated prefix. A non-symbol start has no prefix, a repeated prefix becomes a two-character prefix, and all other prefixed spellings use their first character as the prefix.

_Option uses that split to classify one-character options such as -a as short options and longer or double-prefixed spellings such as --all as long options. It also records both the first prefix character and, for long options, the complete prefix.

When an option is registered, add_option normalizes its spellings, creates an _Option, updates the parser’s recognized prefixes, and inserts each short and long spelling into its corresponding lookup map. _normalize_opt preserves the prefix while applying the context’s token_normalize_func to the option name when one is configured.

The parser first treats an option-like token as a long option. _process_opts separates an explicitly attached value after =, normalizes the option spelling, and calls _match_long_opt. If long matching fails and the token does not use a recognized two-character prefix, the parser falls back to _match_short_opt; otherwise it reports or preserves the unknown option according to ignore_unknown_options.

Sources: src/click/parser.py:111-117, src/click/parser.py:141-155, src/click/parser.py:265-288, src/click/parser.py:120-124, src/click/parser.py:470-485, src/click/parser.py:486-500

How values and short-option clusters are consumed

A matched long option uses _get_value_from_state when its action takes a value. An explicitly attached value is inserted at the front of state.rargs; otherwise the required number of following tokens is consumed, with a special check that prevents an option-looking token from being consumed as an optional value.

_match_short_opt scans the characters after the first prefix one by one, turning each character into a short spelling such as -a. A flag continues through the cluster, while an option that takes a value stops the cluster and treats any remaining characters as the value or as the next input token.

Option dispatch order — How does one option-like token reach its handler?

Evidence

Once a value is selected, _Option.process applies the option action to state.opts: storing, appending, storing a constant, appending a constant, or incrementing a count. It also appends the option’s underlying object to state.order.

Positional values follow a similar finalization path. _Argument.process rejects partially missing multi-value arguments, converts an empty tuple to UNSET, stores the result under the argument destination, and records the argument object in order.

Sources: src/click/parser.py:363-388, src/click/parser.py:430-468, src/click/parser.py:390-418, src/click/parser.py:169-182, src/click/parser.py:191-213

How it connects

The parser is the syntax boundary beneath Click’s higher-level Command and Parameter layer: its own documentation says that those classes wrap it, while types and defaults are implemented above it. The resulting values can then enter parameter processing, where Click type-casts values, checks missingness, and invokes callbacks.

Registered options and arguments originate from the command’s parameter declarations; the decorator API attaches Option and Argument instances to a command’s parameter list. The low-level parser consumes their registered spellings and destinations, but does not itself perform the higher-level parameter interpretation.

For the broader command lifecycle, continue with Commands and Groups and The Parameter Model. For the user-facing distinction between positional arguments and options, see Arguments and Options in Practice.

Sources: src/click/parser.py:224-232, src/click/core.py:2709-2724, src/click/decorators.py:327-341, src/click/decorators.py:355-369, src/click/parser.py:265-296

Key takeaways

  • _OptionParser recognizes command-line syntax before higher-level parameter processing.
  • _process_args_for_options distinguishes --, option-prefixed tokens, and positional-looking tokens.
  • _split_opt and _Option classify short and long option spellings.
  • _process_opts tries long matching first, then short matching when the prefix permits it.
  • _match_short_opt makes combined short flags possible by consuming a cluster character by character.

Want this for your repos?

Try Angada AI Wiki