On Wed, May 4, 2016, at 08:22, Steven D'Aprano wrote:
(1) Because status quo wins. In the absence of a really compelling reason to remove that check, we don't have to justify prohibing duplicate keyword args, we just have to note that it is already in place and so we shouldn't change it.
(2) Duplicate keys in a dict may have side-effects, which mean they do something. Duplicate keyword arguments don't have side-effects (not in the keys at least). So that's a difference.
f(a=1, b=2, **{foo(): bar()}) where foo may return 'a' or 'b', though this is the first that I've heard that the side-effect argument only applies to the keys.
(3) The analogy between function calls and dicts is not really that strong. The dict constuctor intentionally allows certain duplicates:
py> dict({'a': None}, a=2) {'a': 2}
for good reason
but not {**{'a': None}, **{'a': 2}})
(think of over-riding the values provided in the input dict with keyword arguments), but it's not clear that there is an analogy for function calls. Perhaps there is, and if it is a good enough analogy, we might have to re-think the duplicate kwargs situation.
foo(**{'a':None}, a=2) seems like a perfect analogy to me.