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

Tuples as Multi Value Options throw an TypeError #472

Closed
xsteadfastx opened this issue Nov 30, 2015 · 7 comments · Fixed by #1687
Closed

Tuples as Multi Value Options throw an TypeError #472

xsteadfastx opened this issue Nov 30, 2015 · 7 comments · Fixed by #1687
Labels

Comments

@xsteadfastx
Copy link

Hi,

sorry if i do something wrong but i dont even get the example code working. i tried to put this into my code

@cli.command(help='Guess untranslated texts.')                                      
@click.argument('xml_file', type=click.File('r'))                                   
@click.option('--show', is_flag=True, help='Show untranslated texts.')              
@click.option('--html', type=click.File('w'), nargs=1,                              
              help='Write untranslated texts to html file.')                        
@click.option('--edit', type=click.File('w'), nargs=1,                              
              help='Edit untranslated texts.')                                      
@click.option('--csv-export', type=click.File('w'), nargs=1,                        
              help='Export untranslated texts to a csv file.')                      
@click.option('--csv-import', type=(click.File('r'), click.File('w')),              
              help='Imports csv changefile to another xml file.')                   
def untranslated(xml_file, show, html, edit, csv_export, csv_import):

And i will always get this

File "/home/xsteadfastx/Code/my-tools/env/lib/python3.4/site-packages/click/types.py", line 472, in convert
    raise TypeError('It would appear that nargs is set to conflict '
TypeError: It would appear that nargs is set to conflict with the composite type arity.

so i tried it with Python2.7... still the same error. Then i created a fresh Python2.7 virtualenv and used the example

import click


@click.command()
@click.option('--item', type=(unicode, int))
def putitem(item):
    click.echo('name=%s id=%d' % item)


putitem()

and running it with python foo.py still throws the error. I dont know if this is just a question, or if im doing something wrong and i know the "issues" section here is not for questions but maybe its some kind of a bug and i dont know what i else could do about this. so forgive me if its just my problem 😏

@mitsuhiko
Copy link
Contributor

The problem is that Click does not have a way currently to define default values for nargs > 1 when different types are used. A workaround is to set default=(None, None) for instance.

@xsteadfastx
Copy link
Author

Yay, it works! Thank you. By the way... your projects are brilliant and i use them like everyday. So on this way: thank you 😄

@ncrocfer
Copy link

ncrocfer commented Feb 8, 2016

Hello @mitsuhiko ,

Is it possible to use default values for narg > 1 and different types now ? In order to provide defaults host and port for the whatportis (https://github.com/ncrocfer/whatportis/blob/master/whatportis/__main__.py#L42).

And thanks for building click !

@reschkek
Copy link

reschkek commented May 7, 2016

Multi-type defaults appear to work now for nargs > 1 (tested on click 6.2). For options with multiple=True, set the default with a list instead of a tuple.

# foo.py
import click

@click.command()
@click.option('bar', '-b', '--bar', nargs=2, default=(u'rab', 123))
@click.option('baz', '-z', '--baz', type=(unicode, int), default=(u'zab', 456))
@click.option('qub', '-q', '--qub', multiple=True, default=[u'buq', 789])
def main(bar, baz, qub):
    print(bar)
    print(baz)
    print(qub)


if __name__ == '__main__':
    main()
$ python foo.py
(u'rab', 123)
(u'zab', 456)
(u'buq', 789)

@kotoroshinoto
Copy link

if you make a multi-type argument required and set defaults, does that make it not actually behave as if it is required?

@rojaster
Copy link

rojaster commented Oct 4, 2016

Hi, I caught the same bug. And want to get some explanation about the internals of option. am I right or not. All option parameters pass explicitly through a context of decorators of Click? How could I prevent passing an option if it is not defined?

@click.command(...)
@click.argument(...)
@click.option("--r", ...)
@click.option("--i", nargs=3, type=click.Tuple([click.File, click.File, click.Choide(...)]))
def something(arg,opt1,opt2)

I cannot understand why if last option("--i") is not given the program crashes with TypeError:

......
  File "~/.virtualenvs/.../local/lib/python2.7/site-packages/click/types.py", line 472, in convert
    raise TypeError('It would appear that nargs is set to conflict '
TypeError: It would appear that nargs is set to conflict with the composite type arity.

I think it occurs because first option parameter has a default value, but the second one no
I just expected if my option is not set the corresponding variable is None, but it seems not True.

I've added multiple equals True, but it is not a multiple option. I read the Docu and think so a multiple parameter is not for a scenario that I've needed . I want just option with 3 args( --i param param param )

@jrezzende
Copy link

@rojaster as stated by @mitsuhiko:

The problem is that Click does not have a way currently to define default values for nargs > 1 when different types are used. A workaround is to set default=(None, None) for instance.

so, in your case, if you want to have 3 arguments to an option, you have to set "default=(None, None, None)".

@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
9 participants