Install & Compatibility
Where this runs
tested against v0.5.9 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.080s · 18.7MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.7s · import 0.068s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
optgroup
✓ from click_option_group import optgroup
The primary decorator for defining option groups and options within them.
RequiredAnyOptionGroup
✓ from click_option_group import RequiredAnyOptionGroup
Used to define groups where at least one option must be set.
AllOptionGroup
✓ from click_option_group import AllOptionGroup
Used to define groups where all options must be set, or none must be set.
RequiredAllOptionGroup
✓ from click_option_group import RequiredAllOptionGroup
Used to define groups where all options must be set.
MutuallyExclusiveOptionGroup
✓ from click_option_group import MutuallyExclusiveOptionGroup
Used to define groups where only one or none of the options must be set.
RequiredMutuallyExclusiveOptionGroup
✓ from click_option_group import RequiredMutuallyExclusiveOptionGroup
Used to define groups where exactly one option must be set.
This example demonstrates how to create two option groups: 'Server configuration' with standard options and 'Input data sources' using `RequiredMutuallyExclusiveOptionGroup` to ensure only one file type is provided.
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()
Debug
Known issues
breakingAs 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.fixEnsure all optional arguments to `optgroup.group()` or `optgroup()` are passed as keyword arguments (e.g., `optgroup.group('Name', help='Description')`). affects: >=0.5.2
gotchaMixing `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()`.fixUse `optgroup.option()` for all options within a declared `optgroup`. Do not intersperse with `click.option()` for grouped options.
affects: All versions
compatibilityVersion `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.fixEnsure your Click installation is version 8.x (e.g., `click<9`). Check the latest `click-option-group` releases for updates on Click 9.x compatibility.
affects: >=0.5.3 (regarding Click versions >=9.0)
gotchaThe `optgroup` decorator does not support `click.argument()` directly. Arguments must be handled separately outside of an option group.fixDefine Click arguments using `@click.argument()` decorator outside or above any `@optgroup` decorators.
affects: All versions
gotchaCalling `optgroup.option()` without a preceding `optgroup.group()` (or `optgroup()`) declaration for the current command will result in an exception.fixAlways define an option group using `@optgroup.group()` or `@optgroup()` before declaring options within that group using `@optgroup.option()`.
affects: All versions
gotchaWhen 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.fixEnsure that your command-line invocation provides one and only one of the options declared within the mutually exclusive or required option group.
affects: All versions
gotchaWhen 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.fixEnsure that exactly one option from a required and mutually exclusive option group is provided when invoking the command.
affects: All versions
Errors
Common errors & fixes
do not mix optgroup.option() and click.option() decorators!
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
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'
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}')
``` Upgrade
Version history
0.5.9latest on PyPI · released Oct 9, 2025
Audit
Dependencies
clickrequiredCore dependency as it's a Click extension.