This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: dict constructor allows invalid identifiers in **kwargs
Type: behavior Stage: test needed
Components: Interpreter Core Versions: Python 3.2, Python 3.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: alex, benjamin.peterson, eric.smith, mark.dickinson, rhettinger
Priority: low Keywords: patch

Created on 2010-04-16 15:03 by mark.dickinson, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
no_dict_non_string_keyword_args.patch benjamin.peterson, 2010-04-16 21:41
no_dict_non_string_kwarg.patch benjamin.peterson, 2010-04-16 21:48
with_speed_hack.patch benjamin.peterson, 2010-04-16 22:15
refactor_a_bit.patch benjamin.peterson, 2010-04-24 18:06
Messages (13)
msg103330 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-04-16 15:03
In all versions of CPython right now, the following works.

>>> dict({1:2}, **{3:4})
{1: 2, 3: 4}

Other Python implementations raise TypeError for this;  CPython should probably do the same, beginning with deprecating this behaviour in Python 3.2 and removing it in 3.3.

From a python-dev posting[1] by Alex Gaynor:

"""
I ran into the follow behavior while making sure Django works
correctly on PyPy.  The following behavior was observed in all tested
versions of CPython (2.5, 3.1):

>>> def f(**kwargs):
...     print(kwargs)
...
>>> kwargs = {1: 3}
>>>
>>> dict({}, **kwargs)
{1: 3}
>>> f(**kwargs)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: f() keywords must be strings
>>>

This behavior seems pretty strange to me, indeed PyPy gives the
TypeError for both attempts.  I just wanted to confirm that it was in
fact intentional.
"""

Raghuram Devarakonda says (in the same python-dev thread):

"I ran into same issue with Django on Jython yesterday [1] since Jython
too gives TypeError for 'dict({}, **kwargs)'."

Guido, on the suggestion that both the CPython and PyPy behaviour be left as is, and that the behaviour be regarded as implementation defined:

"That is just going to cause some programs to have a portability
surprise. I think one or the other should be fixed. I am fine with declaring dict({}, **{1:3}) illegal, since after all it is abuse of the ** mechanism. We should deprecate it in at least one version though."


[1] http://mail.python.org/pipermail/python-dev/2010-April/099427.html
msg103331 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-04-16 15:15
The issue applies to dict.update as well:

>>> d = {1:2}
>>> d.update({3:4}, **{5:6})
>>> d
{1: 2, 3: 4, 5: 6}
msg103332 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-04-16 15:26
Update:  IronPython also produces a TypeError here (thanks Michael Foord and Dino Viehland).
msg103344 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-04-16 17:48
I don't think this is worth the performance hit or worth the deprecate/remove exercise.  I agree with Guido that we just call this an undefined, implementation specific behavior.

This behavior has existed for a very long time with no ill-effects.  Marking as low priority.
msg103346 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-04-16 18:17
> I agree with Guido that we just call this an undefined, implementation specific behavior.

Actually I think that was exactly what Guido was *disagreeing* with.  :)
msg103347 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-04-16 18:20
I agree with Mark. Guido's point was that if it's implementation defined, you'll have portability problems: http://mail.python.org/pipermail/python-dev/2010-April/099435.html
msg103348 - (view) Author: Alex Gaynor (alex) * (Python committer) Date: 2010-04-16 18:21
Guido seems to be favoring disallowing it, not ignoring it[0].

http://mail.python.org/pipermail/python-dev/2010-April/099435.html
msg103360 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-04-16 21:00
Does this mean that every time someone uses **kwds, that the entire dictionary will need to be scanned for invalid keys?  So every API that accepts and passes through **kwds will be slowed on every time it is called.  Is there any offsetting benefit?
msg103362 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-04-16 21:09
They are already checked for pure python functions.
msg103364 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-04-16 21:41
Here's a patch. It adds a new function, PyArg_ValidateKeywordArguments.
msg103366 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-04-16 21:48
And here's a patch for the correct Python version...
msg103376 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-04-16 22:15
Now with the suggested dictionary speed hack.
msg104115 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-04-24 18:21
Fixed in r80450.
History
Date User Action Args
2022-04-11 14:56:59adminsetgithub: 52666
2010-04-24 18:21:47benjamin.petersonsetstatus: open -> closed
resolution: fixed
messages: + msg104115
2010-04-24 18:06:39benjamin.petersonsetfiles: + refactor_a_bit.patch
2010-04-16 22:15:37benjamin.petersonsetfiles: + with_speed_hack.patch

messages: + msg103376
2010-04-16 21:48:42benjamin.petersonsetfiles: + no_dict_non_string_kwarg.patch

messages: + msg103366
2010-04-16 21:41:47benjamin.petersonsetfiles: + no_dict_non_string_keyword_args.patch
keywords: + patch
messages: + msg103364
2010-04-16 21:09:25benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg103362
2010-04-16 21:00:57rhettingersetmessages: + msg103360
2010-04-16 18:21:49alexsetnosy: + alex
messages: + msg103348
2010-04-16 18:20:22eric.smithsetmessages: + msg103347
2010-04-16 18:17:21mark.dickinsonsetmessages: + msg103346
2010-04-16 17:48:59rhettingersetpriority: normal -> low
nosy: + rhettinger
messages: + msg103344

2010-04-16 15:51:02eric.smithsetnosy: + eric.smith
2010-04-16 15:26:09mark.dickinsonsetmessages: + msg103332
2010-04-16 15:15:55mark.dickinsonsetmessages: + msg103331
2010-04-16 15:03:03mark.dickinsoncreate