Search code examples
pythonpython-3.xwmskeyword-argument

How to pass kwargs further?


I have an outer function wms130.getfeatureinfo in OWSLib, which uses kwargs:

def getfeatureinfo(self, layers=None,
...
                       method='Get',
                       timeout=None,
                       **kwargs
                       ):

and I have usage of kwargs in inner function wms130.__build_getmap_request:

    ...
    request['transparent'] = str(transparent).upper()
    request['bgcolor'] = '0x' + bgcolor[1:7]
    request['exceptions'] = str(exceptions)

    if time is not None:
        request['time'] = str(time)

    if elevation is not None:
        request['elevation'] = str(elevation)

    # any other specified dimension, prefixed with "dim_"
    for k, v in six.iteritems(dimensions):
        request['dim_' + k] = str(v)

    if kwargs:
        for kw in kwargs:
            request[kw]=kwargs[kw]
    return request

Apparently, the intention of the author was to put all keyworded arguments into parameters of HTTP query as is.

Unfortunately, when I pass my kwarg to outer function it has a value

{'MAXCC': '100'}

but when reaching this inner code it has a value

{'kwargs': {'MAXCC': '100'}}

i.e. extra level added. This is because the inner function is called with

# GetMap-Request
        request = self.__build_getmap_request(
            layers=layers,
            styles=styles,
            srs=srs,
            bbox=bbox,
            dimensions=dimensions,
            elevation=elevation,
            format=format,
            size=size,
            time=time,
            transparent=transparent,
            bgcolor=bgcolor,
            exceptions=exceptions,
            kwargs=kwargs)

i.e. outer kwargs is wrapped into single keyworded argument with name kwargs.

The question is dual:

1) How probable it is a bug in OWSLib and the intention was to put kwargs expanded? (I would say it is 99%, because there is no need to add loop to iterate over dictionary with single known entry)

2) How to call inner function in Python to have kwargs passed as kwargs, not as single entry?


Solution

  • Use unpacking to pass the previous kwargs further down. Don't introduce a new keyword argument for it:

    request = self.__build_getmap_request(
                ...
                exceptions=exceptions,
                **kwargs)
    

    All of these keyword arguments and the unpacked kwargs will be captured in the next level kwargs.

    More so, the request dict can be updated using a simple dict.update as opposed to looping:

    request.update(kwargs)