Hi Brandt, very nice PEP. I have two questions here.

First:

- The proposal in its current form is very easy to wrap your head around: "|" takes dicts, "|=" takes anything dict.update does.

I see this asymmetry between the | and |= mentioned a few times in the PEP, but I don't see any rationale other than "the authors have decided". I am not saying that this is the wrong decision, but the reasoning behind this choice is not obvious, and I think it might be a good idea to include the rationale in the PEP. I'd say the asymmetry between list's `__add__` and `__iadd__` semantics is actually fairly confusing for anyone who hasn't encountered it before:

>>> a = []
>>> a = a + "one"                                         
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-f2c4cda7ee5b> in <module>
----> 1 a = a + "one"

TypeError: can only concatenate list (not "str") to list

>>> a += "one"
>>> a
['o', 'n', 'e']
I think most people would be surprised at the difference in semantics here and this also an example of a situation where it's not obvious that the "call `list.extend`" behavior is the right thing to do. It would be nice to see why you rejected:

1. Giving |= `.update` semantics rather than the semantics you chose for |.

2. Giving `|` the same semantics as `|=`.

Second question:

The specification mentions "Dict union will return a new dict containing the left operand merged with the right operand, which must be a dict (or an instance of a dict subclass)." Can you clarify if it is part of the spec that it will always return a `dict` even if one or both of the operands is a dict subclass? You mentioned in another post that this is deliberately intended to be subclass-friendly, but if it always returns `dict`, then I would expect this:

    >>> class MyDict(dict):
    ...    pass
    ...
    >>> MyDict({1: 2}) |
MyDict({3: 4})
    {1: 2, 3: 4}

I realize that there's a lot of precedent for this with other builtin types (int subclasses reverting to int with +, etc), though generally the justifications for this are two-fold:

1. For symmetrical operations like addition it's not obvious which operand's type should prevail, particularly if the two are both different dict subclasses. I think in this case | is already asymmetrical and it would be relatively natural to think of the right thing to do as "make a copy of the LHS then update it with the RHS" (thus retaining the subtype of the LHS).

2. Subclasses may override the constructor in unpredictable ways, so we don't know how to construct arbitrary subtypes. I think this objection could be satisfied by using logic equivalent to `copy.copy` for the LHS when it is a dict subclass, and then using the mapping protocol on the RHS.

Unless there is compelling reason to do otherwise, I am in favor of trying to retain subclass identity after operations, but either way it would be good to be explicit about it in the specification and maybe include a bit of the rationale one way or the other.

Best,
Paul