PEP 584: Apply feedback from the Python-Dev discussion. (#1309)

This commit is contained in:
Brandt Bucher 2020-02-17 12:07:40 -08:00 committed by GitHub
parent 37889fb456
commit 718b393887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 11 deletions

View File

@ -82,6 +82,21 @@ ChainMap will modify the original dict::
{'eggs': 999} {'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 Rationale
========= =========
@ -91,8 +106,10 @@ The new operators will have the same relationship to the
(``+=``) operators have to ``list.extend``. Note that this is (``+=``) operators have to ``list.extend``. Note that this is
somewhat different from the relationship that ``|``/``|=`` have with somewhat different from the relationship that ``|``/``|=`` have with
``set.update``; the authors have determined that allowing the in-place ``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 operator to accept a wider range of types (as ``list`` does) is a more
useful design. 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 Key conflicts will be resolved by keeping the rightmost value. This
matches the existing behavior of similar ``dict`` operations, where 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 Similarly, the *iteration order* of the key-value pairs in the
dictionary will follow the same semantics as the examples above, with dictionary will follow the same semantics as the examples above, with
each newly merged pair being appended (or moved) to the end of the each newly added key (and its value) being appended to the current
current sequence. sequence.
============= =============
Specification Specification
============= =============
Dict union will return a new dict containing the left operand merged Dict union will return a new ``dict`` consisting of the left operand
with the right operand, which must be a ``dict`` (or an instance of a merged with the right operand, each of which must be a ``dict`` (or an
``dict`` subclass). If a key appears in both operands, the last-seen instance of a ``dict`` subclass). If a key appears in both operands,
value (i.e. that from the right-hand operand) wins:: the last-seen value (i.e. that from the right-hand operand) wins::
>>> d = {'spam': 1, 'eggs': 2, 'cheese': 3} >>> d = {'spam': 1, 'eggs': 2, 'cheese': 3}
>>> e = {'cheese': 'cheddar', 'aardvark': 'Ethel'} >>> e = {'cheese': 'cheddar', 'aardvark': 'Ethel'}
@ -166,19 +183,19 @@ An *approximate* pure-Python implementation is::
def __or__(self, other): def __or__(self, other):
if not isinstance(other, dict): if not isinstance(other, dict):
return NotImplemented return NotImplemented
new = self.copy() new = dict(self)
new.update(other) new.update(other)
return new return new
def __ror__(self, other): def __ror__(self, other):
if not isinstance(other, dict): if not isinstance(other, dict):
return NotImplemented return NotImplemented
new = other.copy() new = dict(other)
new.update(self) new.update(self)
return new return new
def __ior__(self, other): def __ior__(self, other):
self.update(other) dict.update(self, other)
return self return self