On Sun, Oct 20, 2019 at 9:27 PM Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
Given that MutableSequence and MutableSet do include __iadd__ and __ior__ respectively, I think the default should obviously be to do the same for MutableMapping if we’re adding one of those methods to dict.

As for adding __add__ or __or__ to Mapping, that’s less obvious, because Set.__or__ exists, but Sequence.__add__ does not. I think if you end up using __or__ I’d argue for it to be added to Mapping, but if you end up using __add__… well, I don’t know why Sequence.__add__ wasn’t included, so I don’t know whether the same rationale applies to Mapping.__add__ or not.

I was there, but I can't recall the details! It looks like the Set and MutableSet APIs are focused on the overloaded operators, while the [Mutable]Sequence APIs are focused on methods. MutableSequence throws in __iadd__ because it's just a wrapper for .extend(), but the same can't be said for Sequence and __add__ -- in fact there's nothing else in Sequence that constructs a new Sequence (whereas Set has a special API for that, Set._from_iterable()). Mapping is more like Sequence in this sense.

Another concern is that we can't add an abstract method to an ABC without creating a backward incompatibility; a class inheriting from Mapping would start failing to instantiate if we were to add Mapping.__add__. But we could implement MutableMapping.__ior__ in the ABC by making it call .update(), just like MutableSequence.__iadd__ calls .extend().

There would still be a lesser problem for classes that use MutableMapping.register() -- if they don't implement __ior__ they don't technically implement the protocol represented by the ABC. But that would only appear if *other* code started calling __ior__. This is more of a gray area. (And I would generally advise against .register() except in cases where one has no control over the source code.)

Note that we can still support Mapping | dict and dict | Mapping, by having __or__ and __ror__ check for Mapping (somehow).

Also note that copy() methods are entirely missing from the ABCs. For [Mutable]Sequence and [Mutable]Mapping this is not a coincidence -- there are no methods that create new instances. For [Mutable]Set I'm not sure about the reason -- perhaps it's in analogy of the others, perhaps it's because you can easily create a copy of a set using s | set().

PS: A curious thing (unrelated to the above points): dict.update() preserves the keys but updates the values (this actually follows from the behavior of __setitem__). This becomes clear when the keys compare equal but have different representations (e.g. 1 == 1.0). The | and |= operator should follow suit.

--
--Guido van Rossum (python.org/~guido)