Click: Tuples as Multi Value Options throw an TypeError

Created on 30 Nov 2015  路  7Comments  路  Source: pallets/click

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 :smirk:

bug

Most helpful comment

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

All 7 comments

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.

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

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 !

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)

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

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 )

@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)".

Was this page helpful?
0 / 5 - 0 ratings

Related issues

joveice picture joveice  路  3Comments

rsyring picture rsyring  路  4Comments

arlyon picture arlyon  路  3Comments

dhstack picture dhstack  路  4Comments

jensens picture jensens  路  4Comments