diff --git a/pep-0584.rst b/pep-0584.rst index b0360ec71..c4fdd83a8 100644 --- a/pep-0584.rst +++ b/pep-0584.rst @@ -82,6 +82,21 @@ ChainMap will modify the original dict:: {'eggs': 999} +------------------ +``dict(d1, **d2)`` +------------------ + +This "neat trick" is not well-known, and only works when ``d2`` is +entirely string-keyed:: + + >>> d1 = {"spam": 1} + >>> d2 = {3665: 2} + >>> dict(d1, **d2) + Traceback (most recent call last): + ... + TypeError: keywords must be strings + + ========= Rationale ========= @@ -91,8 +106,10 @@ The new operators will have the same relationship to the (``+=``) operators have to ``list.extend``. Note that this is somewhat different from the relationship that ``|``/``|=`` have with ``set.update``; the authors have determined that allowing the in-place -operator to accept a wider range of types, as ``list`` does, is a more -useful design. +operator to accept a wider range of types (as ``list`` does) is a more +useful design, and that restricting the types of the binary operator's +operands (again, as ``list`` does) will help avoid silent errors +caused by complicated implicit type casting on both sides. Key conflicts will be resolved by keeping the rightmost value. This matches the existing behavior of similar ``dict`` operations, where @@ -111,18 +128,18 @@ union is not commutative; in general ``d | e != e | d``. Similarly, the *iteration order* of the key-value pairs in the dictionary will follow the same semantics as the examples above, with -each newly merged pair being appended (or moved) to the end of the -current sequence. +each newly added key (and its value) being appended to the current +sequence. ============= Specification ============= -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). If a key appears in both operands, the last-seen -value (i.e. that from the right-hand operand) wins:: +Dict union will return a new ``dict`` consisting of the left operand +merged with the right operand, each of which must be a ``dict`` (or an +instance of a ``dict`` subclass). If a key appears in both operands, +the last-seen value (i.e. that from the right-hand operand) wins:: >>> d = {'spam': 1, 'eggs': 2, 'cheese': 3} >>> e = {'cheese': 'cheddar', 'aardvark': 'Ethel'} @@ -166,19 +183,19 @@ An *approximate* pure-Python implementation is:: def __or__(self, other): if not isinstance(other, dict): return NotImplemented - new = self.copy() + new = dict(self) new.update(other) return new def __ror__(self, other): if not isinstance(other, dict): return NotImplemented - new = other.copy() + new = dict(other) new.update(self) return new def __ior__(self, other): - self.update(other) + dict.update(self, other) return self