On Fri, Mar 8, 2019 at 11:25 AM João Matos <jcrmatos@gmail.com> wrote:
I've just read your PEP 585 draft and have some questions.
When you say

Like the merge operator and list concatenation, the difference operator requires both operands to be dicts, while the augmented version allows any iterable of keys.

>>> d - {'spam', 'parrot'}
Traceback (most recent call last):
TypeError: cannot take the difference of dict and set
>>> d -= {'spam', 'parrot'}
>>> print(d)
{'eggs': 2, 'cheese': 'cheddar'}
>>> d -= [('spam', 999)]
>>> print(d)
{'spam': 999, 'eggs': 2, 'cheese': 'cheddar', 'aardvark': 'Ethel'}

The option d -= {'spam', 'parrot'} where parrot does not exist in the d dict, will raise an exception (eg. KeyNotFound) or be silent?

The option d -= [('spam', 999)] should remove the pair from the dict, correct? But the print that follows still shows it there. It's a mistake or am I missing something?

My understanding is that:

 - (Q1) Attempting to discard a key not in the target of the augmented assignment would not raise a KeyError (or any Exception for that matter).  This is analogous to how the - operator works on sets and is consistent with the pure python implementation towards the bottom of the PEP.
 - (Q2) This one got me as well while implementing the proposal in cpython, but there is a difference in what "part" of the RHS the operators "care about" if the RHS isn't a dict.  The += operator expects 2-tuples and will treat them as (key, value) pairs.  The -= operator doesn't attempt to unpack the RHS's elements as += does and expects keys.  So d -= [('spam', 999)] treated the tuple as a key and attempted to discard it.


    d = {
        'spam': 999,
        ('spam', 999): True
    d -= [('spam', 999)]

Would discard the key ('spam', 999) and corresponding value True.

Which highlights a possibly surprising incongruence between the operators:

    d = {}
    update = [(1,1), (2,2), (3,3)]
    d += update
    d -= update
    assert d == {}  # will raise, as d still has 3 items


    d = {}
    update = {1:1, 2:2, 3:3}
    d += update.items()
    d -= update.items()
    assert d == {}  # will raise, for the same reason
    d -= update.keys()
    assert d == {}  # would pass without issue

That being said I (personally) wouldn't consider it a deal-breaker and still would very much appreciate of the added functionality (regardless of the choice of operator).

- Jim