Rishabh Pandey
Rishabh Pandey

Reputation: 219

multiple values for keyword argument when using **kwargs

Function _mget_search definition will be as,

def _mget_search(query, with_scores=False, count=False, record_term=True,
**kwargs): 

This function called with keyword arguments.

_mget_search(**search_kwargs)

Function parameter search_kwargs contains as,

{'count': False, 'min_score': 20, 'end': 49, 'with_scores': False, 'start': 0, 'query': u'ouuuuu', 'max_score': inf, 'record_term': True}

I am getting this error -

_mget_search() got multiple values for keyword argument 'query'

I am unable to understand why it is happening and how to correct it.

Upvotes: 0

Views: 5486

Answers (5)

Bharel
Bharel

Reputation: 26900

I believe the _mget_search is defined inside a class (you don't show us the entire code), in which case the first parameter should be self.

The error is most commonly caused by calling this:

self._mget_search(**search_kwargs)

While you should have defined it like so:

def _mget_search(self, query, with_scores=False, count=False, record_term=True, **kwargs):

If it is not the issue, then according to the code you've shown, the error should not happen.

Upvotes: 0

e.s.
e.s.

Reputation: 1371

I would bet that something somewhere is also passing a parameter to that function, in addition to the search_kwargs. If it's part of a callback function, there's a good chance the callback is calling it with some parameters and those are getting assigned to the first parameter query.

The only way that I can see you getting that error is if you called your function with a parameter and kwargs, like so:

assuming:

def _mget_search(query, with_scores=False, count=False, record_term=True,
**kwargs): 

then the way to get that error message is:

>>> search_kwargs= {'query': u'ouuuuu', 'count': False, 'min_score': 20, 'end': 49, 'with_scores': False, 'start': 0, 'max_score': inf, 'record_term': True}
>>> _mget_search(some_random_parameter, **search_kwargs)

Here's what I used to try and recreate the error.

def func(a, b=2, **kwargs):
    return '{}{}{}'.format(a, b, kwargs)

Only the last one succeeded in getting that error.

>>> func(**{'a':2, 'b': 3, 'other': 3})
"23{'other': 3}"
>>> func(7, **{'stuff': 5})
"72{'stuff': 5}"
>>> func(2, **{'b': 7})
'27{}'
>>> func(**{'b': 3, 'other': 3, 'a': 5})
"53{'other': 3}"
>>> func(2, **{'a': 5})
TypeError: func() got multiple values for argument 'a'

Upvotes: 1

JGC
JGC

Reputation: 6363

I believe the issue is because query is defined as a positional arg, so when the dictionary you pass with ** is unpacked, the first entry (regardless of its name) is being used for query, then query also appears in the dictionary, hence the multiple values for query.

Try fixing by making query a named arg:

def _mget_search(query='', with_scores=False, count=False, record_term=True, **kwargs):

Alternatively, don't include query in the dictionary when you pass it.

Upvotes: 1

gonczor
gonczor

Reputation: 4146

It's because you are unpacking arguments you are trying to pass. Try to use:

_mget_search(search_kwargs)

EDIT

Let's dive more into this problem. We'll define two functions that and see how they behave when passing various arguments.

In [1]: def fun1(a, b, c):
   ...:     print('Passed arguments: a={} b={} c={}'.format(a, b, c))
   ...:     

In [2]: def fun2(*args):
   ...:     print('Passed args: {}'.format(args))
   ...: 

In [3]: fun1(1, 2, 3)
Passed arguments: a=1 b=2 c=3

In [4]: fun2(1, 2, 3)
Passed args: (1, 2, 3)

In [5]: fun2([1, 2, 3])
Passed args: ([1, 2, 3],)

In [6]: fun2(*[1, 2, 3])
Passed args: (1, 2, 3)

In [7]: fun1(*[1, 2, 3])
Passed arguments: a=1 b=2 c=3

In 3rd call we passed 3 arguments separately which is the same as if we used 7th call where an unpacked list was called. Compare it with situations when fun2 was called.

Upvotes: 0

om tripathi
om tripathi

Reputation: 300

**kwargs allows you to pass keyworded variable length of arguments to a function. You should use **kwargs if you want to handle named arguments in a function. Here is an example to get you going with it:

def greet_me(**kwargs):
    if kwargs is not None:
        for key, value in kwargs.iteritems():
            print "%s == %s" %(key,value)

>>> greet_me(name="yasoob")
name == yasoob

Upvotes: 1

Related Questions