On Tue, Dec 3, 2019 at 2:02 AM Serhiy Storchaka <storchaka@gmail.com> wrote:
I general, I am against this proposition. It makes the language more
complex without adding any benefit. There are already many ways of
merging dicts, including the expression form. It conflicts with Counter.
It can make the code more errorprone because + or | for dicts will no
longer fail immediately.

But if this proposition be accepted, I will try to make it as consistent
and harmless to the language as possible.

02.12.19 21:54, Guido van Rossum пише:
> ## Should the operators be + and +=, or | and |= ?

I argued for | and |= as lesser evil. But there may be a problem. Dict
and dict keys view are interchangeable in the context of some set
operations: "in" checks for existence of the key and iterating yields
keys. Currently both `dictkeys | dict` and `dict | dictkeys` return the
same, the set containing the union of keys.

Hm, I didn't know this. But it shouldn't change. This is a special case in keys(), it seems -- set | dict and dict | set fail. The special case can continue to return the same outcome.
 >>> {1: 2}.keys() | {3}
{1, 3}
 >>> {3} | {1: 2}.keys()
{1, 3}

Your example uses sets -- did you mean {3: 4} instead of {3}?
What it will return if implement | for dicts? It should be mentioned in
the PEP. It should be tested with a preliminary implementation what
behavior is possible and more natural.

Again, Steven, please take note.

> ## What about performance?

It should be mentioned in the PEP that `dict1 | dict2 | dict3` is less
efficient than `{**dict1, **dict2, **dict3}`.

Ditto. (I think this is a much less common use case -- more common is a variable number of dicts, which I would solve with a loop over update() or over |=.)

> ## Other objections

The principal question about the result type was not mentioned above.
`dict | dict` should return an exact dict for dict subclasses for the
same reasons as not including __or__ in the Mapping API. We cannot
guarantee the signature and the behavior of the constructor and
therefore we have no way to create a copy as an instance of general dict
subclass. This is why `dict.copy()` returns an exact dict. This is why
`list + list`, `tuple + tuple`, `str + str`, `set | set`, `frozenset |
frozenset`, etc, etc return an instance of the base class. This is why
all binary operators for numbers (like `int + int`, `float * float`)
return an instance of the base class. Making `dict | dict` returning an
instance of a dict subclass will be an exception to the rule.

Also an important detail, and again I hope that Steven adds this to the PEP.

--Guido van Rossum (python.org/~guido)