New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Properly Handle Duplicate Kwargs #2963
Comments
One one hand, I believe I've run into this issue in another function call in my own code that's basically as follows: objecttype(**{**parameterdict, 'overwrittenparameter': x})
But on the other hand, I can't seem to reproduce it using an inline Cython version of the example in the OP: >>> cprint_kwargs=cython.inline("def f(**kwargs):\n print(kwargs)\nreturn f")
>>> cprint_kwargs(**{'a': 'a', 'a': 'b'})
{'a': 'b'} |
I wonder if Python is handling the kwargs before calling the the function? Can you inline a call to the function? |
Ah, yeah. The dictionary and keyword arguments would have probably been processed and consolidated completely by CPython before being passed into the Cythonized bits. Inlining the function call does produce the broken result: >>> cython.inline("def f(**kwargs):\n print(kwargs)\nf(**{'a': 'a', 'a': 'b'})")
TypeError: function() got multiple values for keyword argument 'a' |
Wrapping the dictionary in any kind of code that constructs a new dictionary does make it work however: >>> cython.inline("return (lambda **kwargs: kwargs)(**{'a': 'a', 'a': 'b'})")
TypeError: function() got multiple values for keyword argument 'a'
>>> cython.inline("return (lambda **kwargs: kwargs)(**dict({'a': 'a', 'a': 'b'}))")
{'a': 'b'} But I do find this a little strange, as I'd naively expect the original example to just call the dictionary constructor and unpackers? |
You didn't say what kind of error you got for this, but my quick guess is that Cython detects that this is redundant and replaces it with (essentially)
which then is illegal. I'm wondering, though: what is the use case for this? |
It was the I hit it with an external library where one class called super and set a kwarg. The parent class then called super as well, trying to set the same kwarg, if one wasn't set already. Instead of using |
Thanks for the detailed bug report. I deoptimised this case since it wasn't a correct transformation. |
This works in python, but not when compiled with Cython. I think it might have something to do with the way kwargs are unpacked.
It's good to point out that this is illegal in python, and will raise a SyntaxError(keyword argument repeated):
print_kwargs(a='a', a='b')
Also worth pointing out that, Interestingly enough, this works the same in python as in cython:
print({'a': 'a', 'a': 'b'})
printing
{'a': 'b'}
The text was updated successfully, but these errors were encountered: