Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Click doesn't respect argument types #1224

Closed
SoniEx2 opened this issue Feb 9, 2019 · 2 comments
Closed

Click doesn't respect argument types #1224

SoniEx2 opened this issue Feb 9, 2019 · 2 comments

Comments

@SoniEx2
Copy link

SoniEx2 commented Feb 9, 2019

With this program:

import click

class Frequency(click.ParamType):
    name = 'frequency'
    def convert(self, value, param, ctx):
        try:
            f = float(value)
            if 0.0 < f < 20000.0:
                return lambda sth: setattr(sth.st, 'freq', f)
            else:
                raise ValueError
        except ValueError:
            self.fail('%s is not a valid frequency' % value, param, ctx)

FREQUENCY = Frequency()

@click.command()
@click.option("-f", "ops", type=FREQUENCY, multiple=True)
@click.option("-n", "--new", "ops", flag_value=lambda sth: 0, multiple=True)
def foo(ops):
    for op in ops:
        print(op, type(op))

if __name__ == "__main__":
    foo()

calling it as ./foo -f 1 should print something along the lines of:

<function Frequency.convert.<locals>.<lambda> at 0x7f339643bc80> <class 'function'>

but instead prints something along the lines of:

1 <class 'str'>
@davidism
Copy link
Member

davidism commented Feb 9, 2019

You named both the options "ops". The parser sees -f and adds the raw value under "ops". The parser doesn't see -n, so it doesn't set the raw value to flag_value. The opts are converted in order. The first option sees the raw value and stores the expected processed value. The second option, which is a String type, sees the same raw value and overwrites the stored processed value.

I'm not entirely clear what you're trying to do with that code, but there's probably a more appropriate construct or processing you can do. Perhaps a different command for new, or something from #257 for a mutually exclusive option. Or most straightforward, give them different names then do extra processing in the command.

@davidism davidism closed this as completed Feb 9, 2019
@SoniEx2
Copy link
Author

SoniEx2 commented Feb 9, 2019

So you mean everything should be the same type= and I should change what I return based on param? I wanna be able to do ./foo -f 1 -n -f 2 -n -f 3 and so on, like the beep command.

I thought each @option had its own type, not each... thingy in def foo([here]): with its own type. This is not clearly documented and the issue should be kept open until it's either clearly documented or changed.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants