Constrained option support for click
Project description
click-constrained-option
click-constrained-option is an extension package that adds constrains to option in Click.
Tested under click 7.x
What it does
Build option that:
- mutually exclusive with others
- depend on other options
- is required conditionally
- is promoted conditionally
- set its default value conditionally
- set its type conditionally
Quick start
pip install click-constrained-option
# example.py
import click
from click_constrained_option import ConstrainedOption
@click.command()
@click.option(cls=ConstrainedOption,
group_require_one=["apple", "orange", "pear"])
@click.option("--apple",
cls=ConstrainedOption,
is_flag=True)
@click.option("--orange",
cls=ConstrainedOption,
is_flag=True)
@click.option("--pear",
cls=ConstrainedOption,
is_flag=True)
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py
Error: require exact one of '--apple' '--orange' '--pear'
$ python example.py --apple --pear
Error: require exact one of '--apple' '--orange' '--pear'
API
kwarg | type | usage |
---|---|---|
allowed_func | function |
return True to indicate allowance, vice versa |
allowed_if | str |
name of the option |
allowed_if_not | str |
name of the option |
allowed_if_all_of | list |
list of the option names |
allowed_if_none_of | list |
list of the option names |
allowed_if_any_of | list |
list of the option names |
allowed_if_one_of | list |
list of the option names |
required_func | function |
return True to indicate requirement, vice versa |
required_if | str |
name of the option |
required_if_not | str |
name of the option |
required_if_all_of | list |
list of the option names |
required_if_none_of | list |
list of the option names |
required_if_any_of | list |
list of the option names |
required_if_one_of | list |
list of the option names |
prompt_func | function |
return True to indicate prompt, vice versa |
prompt_if | str |
name of the option |
prompt_if_not | str |
name of the option |
prompt_if_all_of | list |
list of the option names |
prompt_if_none_of | list |
list of the option names |
prompt_if_any_of | list |
list of the option names |
prompt_if_one_of | list |
list of the option names |
group_require_one | list |
list of the option names |
group_require_any | list |
list of the option names |
group_require_all | list |
list of the option names |
default_func | function |
return a value to use as the default |
type_func | function |
return a valid type of the option |
Note
-
If multiple kwargs are used, then all of them must be satisfied. For example, if
prompt_if
andprompt_if_all_of
are specified, then the option is prompted only when both condition hold true. -
If the custom function has an argument equals an option name in the command, then the value of that option will be used as argument. For example, value of
--foo
will be passed to a custom functionbar(foo)
.
Examples
Dependency and exclusive relation
--username
is allowed if --login
is set:
import click
from click_constrained_option import ConstrainedOption
@click.command()
@click.option("--username",
cls=ConstrainedOption,
allowed_if="login")
@click.option("--login", is_flag=True)
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py --username=foo
Error: Usage for '--username': require '--login'
--login
is allowed if at least one of --userid
and --email
is specified, and --oauth
is not set:
import click
from click_constrained_option import ConstrainedOption
@click.command()
@click.option("--login",
cls=ConstrainedOption,
is_flag=True,
allowed_if_any_of=["userid", "email"],
allowed_if_not="cookie")
@click.option("--userid")
@click.option("--email")
@click.option("--oauth", is_flag=True)
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py --login --userid=foo --oauth
Error: Usage for '--login': conflict with '--oauth'
$ python example.py --login
Error: Usage for '--login': require at least one of '--userid' '--email'
--port
is required if --listen
is an IP address:
import click
import re
from click_constrained_option import ConstrainedOption
@click.command()
@click.option("--port",
cls=ConstrainedOption,
required_func=lambda b: re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", b))
@click.option("--listen")
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py --listen=127.0.0.1
Error: Missing option '--port'
Mutually exclusive group
Exact one of the --order-by-date
--order-by-name
--order-by-rank
must be set:
import click
from click_constrained_option import ConstrainedOption
@click.option(cls=ConstrainedOption,
group_require_one=["order_by_name", "order_by_rank", "order_by_date"])
@click.option("--order-by-name",
cls=ConstrainedOption,
is_flag=True)
@click.option("--order-by-rank",
cls=ConstrainedOption,
is_flag=True)
@click.option("--order-by-date",
cls=ConstrainedOption,
is_flag=True)
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py
Error: require exact one of '--order-by-name' '--order-by-rank' '--order-by-date'
Conditional prompt
--password
will be prompted if one of --userid
--email
is specified
import click
from click_constrained_option import ConstrainedOption
@click.command()
@click.option("--userid")
@click.option("--email")
@click.option("--password",
hide_input=True,
prompt_if_one_of=["userid", "email"])
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py --userid
Password:
Conditional type
Type of --time
will be int if --time-format=timestamp
import click
from click_constrained_option import ConstrainedOption
@click.command()
@click.option("--time-format",
type=click.Choice(["iso-8601", "timestamp"]))
@click.option("--time",
cls=ConstrainedOption,
type_func=lambda time_format: click.INT if time_format == "timestamp" else click.STRING)
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python --time-format="timestamp" --time=str_not_int
Error: Invalid value for '--time': str_not_int is not a valid integer
Conditional default
Default of --lucky
is set through custom function
import click
from click_constrained_option import ConstrainedOption
from random import randint
@click.command()
@click.option("--lucky",
default=lambda : randint(0, 9))
def cli(**kwargs):
click.echo(kwargs)
if __name__ == "__main__":
cli()
$ python example.py
{'lucky': '5'}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for click-constrained-option-0.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | ace4c408c5609ac009087593ea292fb09bb89cc0f9d30ea82292f992015c9681 |
|
MD5 | a4a557f4faf7b430e091648dceb89af6 |
|
BLAKE2b-256 | 6310a522ef19f0af35b23b0f5aebbe73f62b24b63d0a61891a2394b33a0e4490 |
Hashes for click_constrained_option-0.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fe2dd75250434460382725644f6b7e0c09755fe708117c4996c279b570695799 |
|
MD5 | fdd0e564609d10be58ad2a7650270653 |
|
BLAKE2b-256 | b60ac8a2042760ad61cc6ccd5a0496fbfe11cf5a028b2676d381f05586db3c2f |