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.Choice() doesn't like integers while getting --help #784

Closed
jsmedmar opened this issue May 10, 2017 · 7 comments
Closed

click.Choice() doesn't like integers while getting --help #784

jsmedmar opened this issue May 10, 2017 · 7 comments
Labels

Comments

@jsmedmar
Copy link

jsmedmar commented May 10, 2017

click.Choice() doesn't like integers while getting --help.

Given:

click.option(
    "--pk",
    type=click.Choice([1, 2, 3]),
    help="Select the primary key.",
    default=1
    )

Gives:

 803, in show_help
    echo(ctx.get_help(), color=ctx.color)   
  File "{...}/lib/python3.5/site-packages/click/core.py", line 495, in get_help
    return self.command.get_help(self)
  File "{...}/lib/python3.5/site-packages/click/core.py", line 824, in get_help
    self.format_help(ctx, formatter)
  File "{...}/lib/python3.5/site-packages/click/core.py", line 839, in format_help
    self.format_options(ctx, formatter)
  File "{...}/lib/python3.5/site-packages/click/core.py", line 853, in format_options
    rv = param.get_help_record(ctx)
  File "{...}/lib/python3.5/site-packages/click/core.py", line 1602, in get_help_record
    rv = [_write_opts(self.opts)]
  File "{...}/lib/python3.5/site-packages/click/core.py", line 1599, in _write_opts
    rv += ' ' + self.make_metavar()
  File "{...}/lib/python3.5/site-packages/click/core.py", line 1292, in make_metavar
    metavar = self.type.get_metavar(self)   
  File "{...}/lib/python3.5/site-packages/click/types.py", line 140, in get_metavar
    return '[%s]' % '|'.join(self.choices)  
TypeError: sequence item 0: expected str instance, int found
@prusnak
Copy link

prusnak commented Jul 12, 2017

Just hit that issue as well.

Seems that most of the functions of class Choice are expecting self.choices as list of strings, but I guess there is no reason why we should not be able to use ints instead.

I am workarounding the issue by using list of strings though and than calling int(foo) when working with the passed value.

@fdavis fdavis added the bug label May 17, 2018
@d-ganchar
Copy link

@prusnak , @fdavis are you sure that this is bug?
To fix it need to change .join(self.choices) to .join([str(i) for i in self.choices]) here, here and here. But we will have a new problem. List of choices is integer, but we will get value as string from command line. So this means that validation will never be successful(because '1' != 1).
I think you can describe choices as strings and convert type inside command if you need. What do you think?

@cli.command()
@click.option("--pk",
    type=click.Choice(['1', '2', '3']),
    help="Select the primary key.",
    default='1')
def test(pk):
    do_something(int(pk))

@prusnak
Copy link

prusnak commented May 18, 2018

@d-ganchar Probably not a bug per se, but totally not following the Principle of least surprise.

I know it's possible to create a new Choice type (example), but I think passing ints is quite common, so this might deserve a special treatment. Maybe creating a click.ChoiceInt type derived from click.Choice and with overridden methods?

@d-ganchar
Copy link

@prusnak I think that your decision makes sense

@fdavis
Copy link
Contributor

fdavis commented May 18, 2018

While docstring on class Choice says that choices must be a string I agree with @prusnak that its surprising and at the very least we should just enforce the type self.choices in __init__ so it doesn't fail elsewhere

@IKOBH
Copy link

IKOBH commented Oct 29, 2018

Was this issue resolved?

@jcrotts
Copy link
Contributor

jcrotts commented May 7, 2019

We are happy to review PRs on this, but I feel that adding a click.ChoiceInt type or similar will add unnecessary complication to the API.

The user is going to be inputting strings from the command line, so I think the default of specifying a choice as a list of strings makes sense.

I am going to close this for now, but feel free to open if someone has an implementation or a PR.

@jcrotts jcrotts closed this as completed May 7, 2019
@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
Projects
None yet
Development

No branches or pull requests

6 participants