Unexpected keyword argument in python click
Asked Answered
A

3

9
@click.group(context_settings=dict(help_option_names=['-h', '--help']))
def plot_glm():
    pass

@plot_glm.command()
@click.argument('path_nc')
@click.argument('out_path')
@click.argument('var_name')
@click.option('--xaxis_min', default=0.0, help='')
@click.option('--xaxis_max', default=1.1, help='')
@click.option('--xaxis_step', default=0.1, help='')
@click.option('--annotate_date', help='')
@click.option('--yr', default=0, help='')
@click.option('--date', default=-1, help='')
@click.option('--xlabel', default='', help='')
@click.option('--title', default='', help='')
@click.option('--tme_name', default='time', help='')
@click.option('--show_plot', help='')
@click.option('--any_time_data', help='')
@click.option('--format', default='%.2f', help='')
@click.option('--land_bg', help='')
@click.option('--cmap', default=plt.cm.RdBu, help='')
@click.option('--grid', help='')
@click.option('--fill_mask', help='')
def plot_map_from_nc(path_nc, out_path, var_name, xaxis_min=0.0, xaxis_max=1.1, xaxis_step=0.1,
                     annotate_date=False, yr=0, date=-1, xlabel='', title='', tme_name='time', show_plot=False,
                     any_time_data=True, format='%.2f', land_bg=True, cmap=plt.cm.RdBu, grid=False, fill_mask=False)

if __name__ == '__main__':
    plot_glm()

I get this error when using python click library (python version 2.7.11, windows 10, click version 6.6):

    ctx = Context(self, info_name=info_name, parent=parent, **extra)
TypeError: __init__() got an unexpected keyword argument 'any_time_data'

What can I do to fix this error?

Abyss answered 5/5, 2016 at 2:3 Comment(6)
please remove every option not regarding the 'any_time_data' option from your example code and check the syntaxPownall
hmm, not sure how that would help. I would like to retain the other options.Abyss
it would help because some of them are bound to a third module and the first thing happening on execution is first a syntax error and then a NameError, not the TypeError you are getting.Pownall
Cannot reproduce your error message on Click 6.6, python2.7.10, win7. But I observe another error: plt.cm.RdBu is a bound method which takes one argument. So it should be changed to lambda : plt.cm.RdBu(10). After fixing this, your code runs normally on my machine.Bogosian
thanks @gdlmx, I changed to plt.cm.RdBu(10) but still getting the same errorAbyss
By no way should any_time_data go to the __init__ constructor of Context. I don't know how it happens on your machine. It may help if you post the full traceback of your error message.Bogosian
B
11

It seems that you try to call plot_map_from_nc or plot_glm with actual arguments somewhere in your code like this:

plot_map_from_nc(any_time_data=False)
plot_glm(any_time_data=False)

which will generate the same error message that you got.

  File "testClick.py", line 39, in <module>
    plot_glm(any_time_data=False)
  File "c:\winPython\python-2.7.10.amd64\lib\site-packages\click\core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "c:\winPython\python-2.7.10.amd64\lib\site-packages\click\core.py", line 695, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "c:\winPython\python-2.7.10.amd64\lib\site-packages\click\core.py", line 618, in make_context
    ctx = Context(self, info_name=info_name, parent=parent, **extra)
TypeError: __init__() got an unexpected keyword argument 'any_time_data'

Reason for the error

That is because plot_map_from_nc and plot_glm are not normal functions after those click decorators. They are callable objects, whose signature becomes

plot_map_from_nc(args=None, prog_name=None, complete_var=None, standalone_mode=True, **extra)

The type of plot_map_from_nc is click.core.Command and every arguments passed to it will be redirected to click.core.Command.main()

Solution

The correct way to invoke these callable objects is

plot_map_from_nc(sys.argv[1:]) # or
plot_map_from_nc()

If you want to use plot_map_from_nc normally in your code, define it with a different name:

def __plot_map_from_nc__(... , any_time_data=True, ...):
    do_your_job_here
# create an alias
plot_map_from_nc = __plot_map_from_nc__ 
# pass this alias to click
@plot_glm.command()
@click.argument('path_nc') # ...
@click.option('--xaxis_min', default=0.0, help='') # ...
plot_map_from_nc

# Now  plot_map_from_nc becomes a   'click.core.Command'   object  while
# __plot_map_from_nc__ is still a normal function which can be invoke as
__plot_map_from_nc__(... , any_time_data=True, ...)
Bogosian answered 11/5, 2016 at 9:50 Comment(3)
Looking back at the OP code, he has: def plot_map_from_nc(path_nc, out_path, var_name, xaxis_min=0.0, xaxis_max=1.1, xaxis_step=0.1, annotate_date=False, yr=0, date=-1, xlabel='', title='', tme_name='time', show_plot=False, any_time_data=True, format='%.2f', land_bg=True, cmap=plt.cm.RdBu, grid=False, fill_mask=False) which is syntactically incorrect (i.e. not def foo(bar):) or that is where plot_map_from_nc is being called with the argument as you suggest in your answer.Bellda
@busfault : You're correct, the OP code won't even compile. So I think the OP didn't post the full script here. The error may be due to the missing part of his/her code.Bogosian
thanks @gdlmx, I call like this: plot_map_from_nc(..., any_time_data=False, ...). will change to your suggestion and checkAbyss
B
3

I did a little digging. Sometimes the best place to look is in the code that gave you the error: https://github.com/pallets/click/blob/0d48b2fbd256c1c692e3f3ba4c22b102f21f82f7/click/core.py#L879

if args and not ctx.allow_extra_args and not ctx.resilient_parsing:
    ctx.fail('Got unexpected extra argument%s (%s)'
             % (len(args) != 1 and 's' or '',
                ' '.join(map(make_str, args))))

So What I think is that you need to set the allow_extra_args=True or resilient_parsing=True

By default they are:

resilient_parsing=False, allow_extra_args=None,

https://github.com/pallets/click/blob/0d48b2fbd256c1c692e3f3ba4c22b102f21f82f7/click/core.py#L196

If you want, test it out by commenting out that one, I bet that the error you get will be from annotate_date (next alphabetically)

Bellda answered 10/5, 2016 at 20:40 Comment(3)
thanks @busfault, the error message that I am getting is not the same as one you found. My error is got an unexpected keyword argument and not Got unexpected extra argument. Also commenting out the line you suggested does not do away with the error eitherAbyss
Thanks! sorry about messing that up!Bellda
thanks @busfault, for looking, i really appreciate thatAbyss
M
3

I wanted to add to @gdlmx's answer because I tried running the code from their answer and ran into errors that took a little bit to parse through. I'd add this as a comment but unfortunately I don't have enough karma.

The code from this block will raise an error: "SyntaxError: invalid syntax" on the last line.

def __plot_map_from_nc__(... , any_time_data=True, ...):
    do_your_job_here
# create an alias
plot_map_from_nc = __plot_map_from_nc__ 
# pass this alias to click
@plot_glm.command()
@click.argument('path_nc') # ...
@click.option('--xaxis_min', default=0.0, help='') # ...
plot_map_from_nc

The thing that seems to work for this is:

#define your original function
def __plot_map_from_nc__(... , any_time_data=True, ...):
    do_your_job_here
#put @ decorator on a regular decorator expression
@plot_glm.command()
@click.argument('path_nc') # ...
@click.option('--xaxis_min', default=0.0, help='') # ...
def plot_map_from_nc(... , any_time_data=True, ...):
    __plot_map_from_nc__(... , any_time_data=True, ...)

Basically, this traditional decorator definition gives you a define block to put your @ decorator syntax on. Honestly, this probably isn't the best way to handle this, but because click uses so many decorators for setting up your CLI, it'd be unreasonable to add all of your commands with the traditional syntax.

Merrell answered 22/7, 2019 at 18:10 Comment(1)
This is SO - not reddit - and we use "rep" not "karma" :-)Kampala

© 2022 - 2024 — McMap. All rights reserved.