vijos/vj4

post() got multiple values for keyword argument 'admin'

Closed this issue · 7 comments

Mar 03 03:13:19 localhost.localdomain bash[24622]: [E 180303 03:13:19 web_protocol:356] Error handling request
Mar 03 03:13:19 localhost.localdomain bash[24622]: Traceback (most recent call last):
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/usr/lib64/python3.6/site-packages/aiohttp/web_protocol.py", line 416, in start
Mar 03 03:13:19 localhost.localdomain bash[24622]: resp = yield from self._request_handler(request)
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/usr/lib64/python3.6/site-packages/aiohttp/web.py", line 325, in _handle
Mar 03 03:13:19 localhost.localdomain bash[24622]: resp = yield from handler(request)
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/usr/lib64/python3.6/site-packages/aiohttp/web_middlewares.py", line 93, in impl
Mar 03 03:13:19 localhost.localdomain bash[24622]: return (yield from handler(request))
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/home/algo/vj4/vj4/handler/base.py", line 224, in __iter__
Mar 03 03:13:19 localhost.localdomain bash[24622]: yield from super(Handler, self).__iter__()
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/usr/lib64/python3.6/site-packages/aiohttp/web_urldispatcher.py", line 770, in __iter__
Mar 03 03:13:19 localhost.localdomain bash[24622]: resp = yield from method()
Mar 03 03:13:19 localhost.localdomain bash[24622]: File "/home/algo/vj4/vj4/handler/base.py", line 450, in wrapped
Mar 03 03:13:19 localhost.localdomain bash[24622]: return await coro(self, **kwargs, **await self.request.post())
Mar 03 03:13:19 localhost.localdomain bash[24622]: TypeError: post() got multiple values for keyword argument 'admin'

This happens when we try to update the privilege setting of domains.
It is due to the MultiDictProxy object with multiple values of the same key in the post payload, which is passed as the parameters of the function.

The problem can be resolved by changing

    return await coro(self, **kwargs, **await self.request.post())

at line 448 of vj4/handler/base.py
into

    return await coro(self, **kwargs, **dict(await self.request.post()))
twd2 commented

We should fix the code that generates multiple admin arguments.

This should be a bug in python 3.6.

Python 3.5.3 (default, Sep 27 2018, 17:25:39) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import multidict
>>> d = multidict.CIMultiDict([('a', 1), ('a', 2)])
>>> def foo(**kwargs): pass
... 
>>> foo(**d)
>>> foo(**{}, **d)
Python 3.6.7 (default, Oct 21 2018, 08:08:16) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import multidict
>>> d = multidict.CIMultiDict([('a', 1), ('a', 2)])
>>> def foo(**kwargs): pass
... 
>>> foo(**d)
>>> foo(**{}, **d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for keyword argument 'a'

Meanwhile we can workaround the problem by removing post_argument, since the handler is using custom argument processing.

We cannot easily remove post_argument since csrf_token depends on it.

The issue was fixed by a8887ea. We should file a bug for python.

Filed https://bugs.python.org/issue35634. Closing this issue.