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. IOW, 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 Similarly, 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