[Python-ideas] dictionary constructor should not allow duplicate keys
Terry Reedy
tjreedy at udel.edu
Tue May 3 23:23:39 EDT 2016
On 5/3/2016 8:46 PM, Luigi Semenzato wrote:
> On Tue, May 3, 2016 at 4:51 PM, Steven D'Aprano <steve at pearwood.info> wrote:
The thread seems to partly be based on a confusion between literals and
displays, which led to dict displays being called dict literals. A
literal defines an int or string at the initial lexing or tokenizing
phase of the parser. A display, like comprehensions, abbreviates
runtime code for creating a composite collection object.
>> What counts as "duplicate keys"? I presume that you mean that two keys
>> count as duplicate if they hash to the same value, and are equal. But
>> you keep mentioning "literals" -- does this mean you care more about
>> whether they look the same rather than are the same?
>
> Correct. The errors that I am guessing matter the most are those for
> which folks copy-paste a key-value pair, where the key is a literal
> string, intending to change the key, and then forget to change it.
>
>> # duplicate literals, forbidden
>> d = {100: 1, 100: 2}
>
> Correct. Possibly caught during parsing.
The above is equivalent to and an abbreviation of
d = {}; d[100] = 1; d[100] = 2
A bit silly, but quite legal. Every value replacement necessarily
involves a 'duplicate key'. Both of the above are also equivalent to
d = {a:b for a,b in ((100,1), (100,2))}
This is also equivalent to
d = {}
for a, b in ((100,1), (100,2)):
d[a] = b
which is close to the python version of how the comprehension would
implemented in python.
Here is a 5th version, which I expect is close to the actual CPython
code for a dict display.
tem = [100, 1, 100, 2] # as in the top of the virtual machine stack
n = 4 # number of items in display = 2 * number of pairs
d = {}
for i in range(-n, 0, 2):
d[tem[i]] = tem[i+1]
We have 5 equivalent snippets, each of which could have the same bug.
Why single out just one to raise an exception? My guess is that it is
partly from mistakenly thinking of the one as a like a lexer literal
rather than as runtime code.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list