Click Option Group
click-option-group is a Click-extension package that provides the functionality for creating option groups in Click-based command-line interfaces. It allows for logical structuring of CLI options and defining specific behaviors and relationships among grouped options, such as mutually exclusive or required option sets. The package is actively maintained, with its current version being 0.5.9, and receives regular updates.
Common errors
-
do not mix optgroup.option() and click.option() decorators!
cause The `click-option-group` library does not allow mixing `optgroup.option()` and `click.option()` decorators directly within the same decorator chain for a command. All grouped options must be declared using `optgroup.option()` under an `optgroup.group()`, and Click's native `click.option()` decorators should be placed outside the option group's decorator block.fixEnsure that all options belonging to an `optgroup.group()` are defined using `@optgroup.option()`. Place any standard Click options using `@click.option()` either before or after the entire `optgroup.group()` block. For example: ```python import click from click_option_group import optgroup @click.command() @click.option('--global-param') @optgroup.group('My Group') @optgroup.option('--foo') @optgroup.option('--bar') def cli(global_param, foo, bar): pass ``` -
Missing declaration of the option group
cause This error occurs when an `@optgroup.option()` decorator is used without an preceding `@optgroup.group()` or `@optgroup()` decorator to define the option group it belongs to. Every grouped option must be explicitly associated with a declared group.fixAlways declare an option group using `@optgroup.group()` or `@optgroup()` before using `@optgroup.option()` to add options to it. For example: ```python import click from click_option_group import optgroup @click.command() @optgroup.group('My Group', help='A group of options') @optgroup.option('--foo', help='Foo option') @optgroup.option('--bar', help='Bar option') def cli(foo, bar): pass ``` -
'_Optgroup' object has no attribute 'argument'
cause The `click-option-group` library is designed to manage `options` within groups, not `arguments`. Click's `argument` decorator cannot be used directly with `optgroup` as `_Optgroup` objects do not provide an `argument` method.fixIf you need to define positional arguments, use Click's native `@click.argument()` decorator outside of any `optgroup.group()` definition. Option groups are exclusively for `click.option`-like constructs. For example: ```python import click from click_option_group import optgroup @click.command() @optgroup.group('My Options') @optgroup.option('--name', help='A name option') @click.argument('files', nargs=-1) def cli(name, files): click.echo(f'Name: {name}, Files: {files}') ```
Warnings
- breaking As of v0.5.2, all arguments to the `optgroup` decorator, except for `name`, must be passed as keyword-only arguments. Positional arguments for `cls`, `help`, or `attrs` will raise an error.
- gotcha Mixing `optgroup.option()` and `click.option()` decorators on the same command is not supported and will raise an exception. All options intended to be part of an `optgroup` must use `optgroup.option()`.
- compatibility Version `0.5.3` specifically bumped the Click dependency to `<9`, indicating potential incompatibility with Click 9.x and later. Users on Click 9.x may encounter issues.
- gotcha The `optgroup` decorator does not support `click.argument()` directly. Arguments must be handled separately outside of an option group.
- gotcha Calling `optgroup.option()` without a preceding `optgroup.group()` (or `optgroup()`) declaration for the current command will result in an exception.
- gotcha When defining an option group with mutual exclusivity or requiring one of its options, users must provide exactly one of the options from that group. Failure to do so will result in a validation error indicating missing required options.
- gotcha When an option group is defined as both `required=True` and `mutually_exclusive=True`, the command will raise an `Error: Missing one of the required mutually exclusive options` if no option from that group is provided by the user.
Install
-
pip install click-option-group
Imports
- optgroup
from click_option_group import optgroup
- RequiredAnyOptionGroup
from click_option_group import RequiredAnyOptionGroup
- AllOptionGroup
from click_option_group import AllOptionGroup
- RequiredAllOptionGroup
from click_option_group import RequiredAllOptionGroup
- MutuallyExclusiveOptionGroup
from click_option_group import MutuallyExclusiveOptionGroup
- RequiredMutuallyExclusiveOptionGroup
from click_option_group import RequiredMutuallyExclusiveOptionGroup
Quickstart
import click
from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup
@click.command()
@optgroup.group('Server configuration', help='The configuration of some server connection')
@optgroup.option('-h', '--host', default='localhost', help='Server host name')
@optgroup.option('-p', '--port', type=int, default=8888, help='Server port')
@optgroup.option('-n', '--attempts', type=int, default=3, help='The number of connection attempts')
@optgroup.option('-t', '--timeout', type=int, default=5, help='The server response timeout')
@optgroup.group('Input data sources', cls=RequiredMutuallyExclusiveOptionGroup, help='The sources of the input data')
@optgroup.option('--tsv-file', type=click.Path(), help='CSV/TSV input data file')
@optgroup.option('--json-file', type=click.Path(), help='JSON input data file')
@click.option('--debug/--no-debug', default=False, help='Debug flag')
def cli(**params):
click.echo(f"Running with parameters: {params}")
if __name__ == '__main__':
cli()