As it turns out I misunderstood the usage of multiple=True when using @click.option.

For example is it possible to invoke -t multiple times

python selectTools.py -t tool1 -t tool3 -t tool2

by using

@click.option('--tools', '-t', type=click.Choice(['tool1', 'tool2', 'tool3']), multiple=True)

and thus makes the selection of several tools from the choices possible.

Answer from rienix on Stack Overflow
🌐
Click Documentation
click.palletsprojects.com › en › stable › options
Options — Click Documentation (8.5.x)
A simple click.Option takes one option name. By default, it’s assumed that the decorated function argument is not required and the expected type is str.
🌐
Click Documentation
click.palletsprojects.com › en › stable › parameter-types
Parameter Types — Click Documentation (8.5.x)
If None, keep Python’s default, which is str. Useful to convert to pathlib.Path. Changed in version 8.5.1: Reveal the actual type of the value as converted from raw input. ... Changed in version 8.1: Added the executable parameter. Changed in version 8.0: Allow passing path_type=pathlib.Path. Changed in version 6.0: Added the allow_dash parameter. When type is not given, Click infers it from default.
Discussions

multiple input types ("either / or") for option in python click - Stack Overflow
Is it possible to specify two input types for a click.option, one of which the supplied value has to be in? In a normal python function with typing, I'd declare it like so: from typing import Union... More on stackoverflow.com
🌐 stackoverflow.com
python - How to pass several list of arguments to @click.option - Stack Overflow
Copy$ python script1.py --option1 four 4 Error: Option '--option1' requires 3 arguments. ... A default value can be specified when the option is created. Note that the default value should also be a tuple of three str values to avoid any unexpected behavior. Particularly, it should not be a list (or any other mutable type), as mutable default arguments can cause unexpected behavior. Call the code with this change script2.py: Copy@click... More on stackoverflow.com
🌐 stackoverflow.com
Documentation: mention required=True for options
This is never mentioned as a possibility for click.option anywhere in the docs as far as I can tell (or at least it should be more prominent, maybe a section). (it talks about it in click.argument, but its unclear that it exists for both... More on github.com
🌐 github.com
12
February 4, 2016
click vs. argparse: Should the 'multiple' parameter be equivalent to 'nargs'?
For example, I have an option that takes up to three values, where the last two must be integers. import click @click.command() @click.option("--item", nargs=3, type=click.Tuple([str, int, int])) def putitem(item): name, i, j = item click.echo(f"name={name} id={i} count={j}") if __name__ == "__main__": putitem() "--item yourmom 10 1" name=yourmom id=10 count=1 "click.Tuple" and "name, i, j = item" should be self-explanatory. https://click.palletsprojects.com/en/8.1.x/options/#multi-value-options the only limitation is that "nargs" value must be known. click seems to like unambiguous commands. Error: Option '--item' requires 3 arguments. then again I can't make the third argument optional, can I? BUT, you can be tricksy. i'd suggest other libs that offers this functionality.. since fiddling with how the lib works will invariably lead to errors .. https://stackoverflow.com/a/44056564 More on reddit.com
🌐 r/learnpython
4
2
July 12, 2023
🌐
Readthedocs
pocoo-click.readthedocs.io › en › latest › options
Options — click
In this case the option is of type INT because the default value is an integer. Sometimes, you have options that take more than one argument. For options, only a fixed number of arguments is supported. This can be configured by the nargs parameter. The values are then stored as a tuple. @click.command() @click.option('--pos', nargs=2, type=float) def findme(pos): click.echo('%s / %s' % pos)
🌐
Click Documentation
click.palletsprojects.com › en › stable › parameters
Parameters — Click Documentation (8.5.x)
Click supports only two principle types of parameters for scripts (by design): options and arguments.
🌐
Click Documentation
click.palletsprojects.com
Welcome to Click — Click Documentation (8.5.x)
import click @click.command() @click.option('--count', default=1, help='Number of greetings.') @click.option('--name', prompt='Your name', help='The person to greet.') def hello(count, name): """Simple program that greets NAME for a total of COUNT times.""" for x in range(count): click.echo(f"Hello {name}!") if __name__ == '__main__': hello() ... $ python hello.py --help Usage: hello.py [OPTIONS] Simple program that greets NAME for a total of COUNT times.
Find elsewhere
🌐
Click Documentation
click.palletsprojects.com › en › stable › api
API — Click Documentation (8.5.x)
Python opens stdout and stderr with errors="surrogateescape". ... filename (str | bytes | PathLike[str] | PathLike[bytes]) – formats a filename for UI display. This will also convert the filename into unicode without failing. shorten (bool) – this optionally shortens the filename to strip of the path that leads up to it. ... class click.Command(name, context_settings=None, callback=None, params=None, help=None, epilog=None, short_help=None, options_metavar='[OPTIONS]', add_help_option=True, no_args_is_help=False, hidden=False, deprecated=False)¶
🌐
ZetCode
zetcode.com › python › click
Python click - creating command line interfaces
January 29, 2024 - #!/usr/bin/python import click ... -w sky --word forest --word rock -w cloud sky forest rock cloud · The click.File type declares a parameter to be a file for reading or writing....
🌐
Reddit
reddit.com › r/learnpython › grouping options in click (python)
r/learnpython on Reddit: Grouping options in Click (Python)
June 6, 2025 - import click from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup @click.command() @click.option('--option-1', required=True, help="option 1") @optgroup.group('group', cls=RequiredMutuallyExclusiveOptionGroup, help='group for option') @optgroup.option('--option-2', help="option 2") @optgroup.option('--option-3', help="option 3") def handler(**kwargs): pass Share
🌐
Devnet-academy
docs.devnet-academy.com › docs › click_v7.1.2 › options.html
Options — Click Documentation (7.x)
If no default value is provided, the type is assumed to be STRING. Unless a name is explicitly specified, the name of the parameter is the first long option defined; otherwise the first short one is used. By default, options are not required, however to make an option required, simply pass in required=True as an argument to the decorator. @click.command() @click.option('--n', default=1) def dots(n): click.echo('.' * n)
🌐
Click Documentation
click.palletsprojects.com › en › stable › advanced
Advanced Patterns — Click Documentation (8.5.x)
Note: an actual implementation of a --version parameter that is reusable is available in Click as click.version_option().
🌐
Click Documentation
click.palletsprojects.com › en › stable › arguments
Arguments — Click Documentation (8.5.x)
@click.command(context_settings={"ignore_unknown_options": True}) @click.argument('files', nargs=-1, type=click.Path()) def touch(files): """Print all FILES file names.""" for filename in files: click.echo(filename)
Top answer
1 of 6
93

If you don't insist on passing something that looks like a list, but simply want to pass multiple variadic arguments, you can use the multiple option.

From the click documentation

@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
    click.echo('\n'.join(message))
$ commit -m foo -m bar
foo
bar
2 of 6
41

You can coerce click into taking multiple list arguments, if the lists are formatted as a string literals of python lists by using a custom option class like:

Custom Class:

import click
import ast

class PythonLiteralOption(click.Option):

    def type_cast_value(self, ctx, value):
        try:
            return ast.literal_eval(value)
        except:
            raise click.BadParameter(value)

This class will use Python's Abstract Syntax Tree module to parse the parameter as a python literal.

Custom Class Usage:

To use the custom class, pass the cls parameter to @click.option() decorator like:

@click.option('--option1', cls=PythonLiteralOption, default=[])

How does this work?

This works because click is a well designed OO framework. The @click.option() decorator usually instantiates a click.Option object but allows this behavior to be over ridden with the cls parameter. So it is a relatively easy matter to inherit from click.Option in our own class and over ride the desired methods.

In this case we over ride click.Option.type_cast_value() and then call ast.literal_eval() to parse the list.

Test Code:

@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('--option1', cls=PythonLiteralOption, default=[])
@click.option('--option2', cls=PythonLiteralOption, default=[])
def cli(option1, option2):
    click.echo("Option 1, type: {}  value: {}".format(
        type(option1), option1))
    click.echo("Option 2, type: {}  value: {}".format(
        type(option2), option2))

# do stuff
if __name__ == '__main__':
    import shlex
    cli(shlex.split(
        '''--option1 '["o11", "o12", "o13"]' 
        --option2 '["o21", "o22", "o23"]' '''))

Test Results:

Option 1, type: <type 'list'>  value: ['o11', 'o12', 'o13']
Option 2, type: <type 'list'>  value: ['o21', 'o22', 'o23']
🌐
Medium
medium.com › @afimaamedufie › getting-acquainted-with-python-click-fbfccf2bd990
Getting Acquainted with Python Click | by Afi Maame Dufie | Medium
November 25, 2022 - A Decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Click commands are created with the click.command decorator. Values are passed to the commands via options or arguments.
🌐
AssemblyAI
assemblyai.com › blog › the-definitive-guide-to-python-click
The Definitive Guide to Python Click
July 28, 2021 - Upon creation of our group and declaring it in main, we should have an automatically generated "--help" option, like so: Yours shouldn’t have all the commands listed yet, but that’s just a sneak peak at what we’re going to build. NOTE - all commands must be defined between main() and our click.group decorator. Now that we’ve created our first group in Python Click, let’s add our first command to it. Let’s make a command that will check the context for us to confirm that we have the right type.
🌐
Real Python
realpython.com › python-click
Click and Python: Build Extensible and Composable CLI Apps – Real Python
March 18, 2026 - Because the user input must be an integer number, you use click.INT to define the parameter’s type. The default behavior of tail is to display the final ten lines, so you set default to 10 and discover another cool feature of Click’s options.
🌐
PyPI
pypi.org › project › click
click · PyPI
2 weeks ago - import click @click.command() @click.option("--count", default=1, help="Number of greetings.") @click.option("--name", prompt="Your name", help="The person to greet.") def hello(count, name): """Simple program that greets NAME for a total of COUNT times.""" for _ in range(count): click.echo(f"Hello, {name}!") if __name__ == '__main__': hello() $ python hello.py --count=3 Your name: Click Hello, Click!
🌐
Zonca
zonca.dev › posts › 2022-10-26-click-commandline-class-arguments
Generate Click command line options dynamically from class arguments – Andrea Zonca
October 26, 2022 - We also use Python typing so we can pass that to Click. class AClass: def __init__( self, a: str, b: int): pass · class BClass: def __init__( self, c: float, d: bool, under_score: str): pass · def options_from_class(cls): def decorator(f): for par in inspect.signature(cls.__init__).parameters.values(): if par.name not in ["self"]: click.option("--" + par.name, required=True, type=par.annotation)(f) return f return decorator ·
🌐
GitHub
github.com › pallets › click › issues › 514
Documentation: mention required=True for options · Issue #514 · pallets/click
February 4, 2016 - This is never mentioned as a possibility for click.option anywhere in the docs as far as I can tell (or at least it should be more prominent, maybe a section). (it talks about it in click.argument, but its unclear that it exists for both...
Author: pallets