
Hi all, I've recently filled the issue 244 (dict.update() doesn't support keywords argument), and tried to solve it in a naive way, just modifying the applevel definition to: def update(d, o, **kwargs): if hasattr(o, 'keys'): for k in o.keys(): d[k] = o[k] else: for k,v in o: d[k] = v for k in kwargs: d[k] = kwargs[k] But it simply doesn't work: test_dictobject.py[34] .......................FF......... __________________________________________________________________________________________________________________________________________ __________________________________________ entrypoint: AppTest_DictObject().test_update_kwargs ___________________________________________ def test_update_kwargs(self): d = {} E d.update(foo='bar', baz=1)
(application-level) TypeError: update() got 2 unexpected keyword arguments
[/home/leo/src/pypy-dist/pypy/objspace/std/test/None</home/leo/src/pypy-dist/pypy/interpreter/gateway.py:754>:3] __________________________________________________________________________________________________________________________________________ ______________________________________ entrypoint: AppTest_DictObject().test_update_dict_and_kwargs ______________________________________ def test_update_dict_and_kwargs(self): d = {} E d.update({'foo': 'bar'}, baz=1)
(application-level) TypeError: update() got an unexpected keyword argument 'baz'
[/home/leo/src/pypy-dist/pypy/objspace/std/test/None</home/leo/src/pypy-dist/pypy/interpreter/gateway.py:754>:3] Why?. Should it work or is the lack of kwargs support a known limitation? -- Leonardo Soto M.

Hi Leonardo, On Sat, Jul 29, 2006 at 09:11:14PM -0400, Leonardo Soto wrote:
This is a bit messy. It's an app-level definition but it goes through the interp-level gateway code via the multimethod logic. The first thing to change is the declared signature of the dict_update multimethod, also in dicttype.py: dict_update = SMM('update', 2, defaults=((),), doc="...") This means "two arguments with a default of () for the second one". Note that it's where the default comes from, too; not from the "def update(d, o)" implementation. Note first a difficulty: if we were implementing this method in pure Python, we couldn't say 'def update(self, o, **kwargs)' because there is a name clash between 'o' and the keywords, preventing an explicit 'o' keyword from being passed. To solve this we would have to declare it 'def update(self, *args, **kwargs)'. The equivalent solution here is: dict_update = SMM('update', 1, general__args__=True, doc="...") ^^^^^^^^^^^^^^^^^^^^^^^^ def update(d, *args, **kwargs): if len(args) > 1: raise TypeError("update takes at most 1 (non-keyword) argument") ... dict_update__ANY = app.interphook("update") ^^^^ But it doesn't work yet, because I'm just discovering that we have no support for *args/**kwargs in app.interphook()! Trying to fix this now... Armin

Hi Leonardo, On Sat, Jul 29, 2006 at 09:11:14PM -0400, Leonardo Soto wrote:
This is a bit messy. It's an app-level definition but it goes through the interp-level gateway code via the multimethod logic. The first thing to change is the declared signature of the dict_update multimethod, also in dicttype.py: dict_update = SMM('update', 2, defaults=((),), doc="...") This means "two arguments with a default of () for the second one". Note that it's where the default comes from, too; not from the "def update(d, o)" implementation. Note first a difficulty: if we were implementing this method in pure Python, we couldn't say 'def update(self, o, **kwargs)' because there is a name clash between 'o' and the keywords, preventing an explicit 'o' keyword from being passed. To solve this we would have to declare it 'def update(self, *args, **kwargs)'. The equivalent solution here is: dict_update = SMM('update', 1, general__args__=True, doc="...") ^^^^^^^^^^^^^^^^^^^^^^^^ def update(d, *args, **kwargs): if len(args) > 1: raise TypeError("update takes at most 1 (non-keyword) argument") ... dict_update__ANY = app.interphook("update") ^^^^ But it doesn't work yet, because I'm just discovering that we have no support for *args/**kwargs in app.interphook()! Trying to fix this now... Armin
participants (2)
-
Armin Rigo
-
Leonardo Soto