multiple input types ("either / or") for option in python click
Asked Answered
S

1

6

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

def fun(x: Union[int, str]):
    if isinstance(x, str):
        x = int(x)
    return x**2

so x should be either an int or str.

In click I want to achieve the same thing, just with the addition that the script fails when the input type isn't in the defined ones.

I've tried

@click.option('-x', type=(click.INT, click.STRING))

but that seems to be only for occasions with multiple arguments.

Shoat answered 30/3, 2021 at 17:21 Comment(3)
if you want it to convert string to int then maybe simply use int(variable) without checking type. If you use int(integer_number) then you get the same integer number. If you use int(string_number) then you get value converted to integer number.Allan
@Allan this is just a toy example - in the real application, the two types would be a file or the already parsed contents of the fileShoat
I don't use ``click` and I don't know how you want to recognize file and context - for Python both would be only strings. I would rather use two different variables for this - ie. -f for file and -t for text/content - first function (assigned to -f) would load file and run second function (assigned to -t).Allan
F
2

Click does not directly support Union option/argument types (unlike its Tuple type support). It has been raised as a feature request at least twice (1, 2), but in both cases these have been closed with the advise to use a custom param type instead.

    class Union(click.ParamType):
    def __init__(self, types):
        self.types = types

    def convert(self, value, param, ctx):
        for type in self.types:
            try:
                return type.convert(value, param, ctx)
            except click.BadParameter:
                continue

        self.fail("Didn't match any of the accepted types.")

The click-param add-on module also provides a union type called FirstOf

    @click.option('-x', type=FirstOf(click.INT, click.STRING))
Fetching answered 4/6 at 11:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.