
Feb. 6, 2020
12:38 p.m.
One issue that's come up during PR review with Guido and Serhiy is, when evaluating `a | b`, whether or not the default implementation should call an overridden `copy()` method on `a` in order to create an instance of the correct subclass (rather than a plain-ol' `dict`). For example, `defaultdict` works correctly without any additional modification: ```
from collections import defaultdict i = defaultdict(int, {1: 1, 2: 2}) s = defaultdict(str, {2: "2", 3: "3"}) i | s defaultdict(<class 'int'>, {1: 1, 2: '2', 3: '3'}) s | i defaultdict(<class 'str'>, {2: 2, 3: '3', 1: 1})
So this has immediate benefits for both usability and maintenance: subclasses only need to override `copy()` to get working `__or__`/`__ror__` behavior. While this isn't what `list` and `set` do, for example, I argue that `dict` is more often subclassed, and we shouldn't blindly follow the precedent of their behavior when designing a new API for `dict`.
We decided to bring the discussion here to get input from a larger audience. I'm currently +0 on calling `copy()`, but I know Steven feels a bit more strongly about this than I do:
> I think the standard handling of subclasses in Python builtins is wrong, and I don't wish to emulate that wrong behaviour without a really good reason. Or at least a better reason than "other methods break subclassing unless explicitly overloaded, so this should do so too". Or at least not without a fight :-)
The more detailed thread of discussion starts at https://github.com/python/cpython/pull/12088#issuecomment-582609024 (note that we are no longer considering calling an overridden `update` method).