![](https://secure.gravatar.com/avatar/fba529808415c562f826c85b9fe62991.jpg?s=120&d=mm&r=g)
Hey guys, I was just about to fix dict's get() to call __missing__ if a key doesn't exist (before returning the default value) but realized that although small, that patch can cause future issues. Right now there's an inconsistency:
from collections import UserDict class A(dict): ... def __missing__(self, key): ... print(key) ... class B(UserDict): ... def __missing__(self, key): ... print("UserDict", key) ... a = A() b = B() a.get(123) b.get(123) UserDict 123 a.get(123, "abc") 'abc' b.get(123, "abc") UserDict 123
The reason for this inconsistency is because the Mapping abc and dict behave differently. Dict's get doesn't call __getitem__ which causes the call not to route to __missing__. MutableMapping's get calls __getitem__, which UserDict implements as a check to __missing__ as well. According to the doc, the specification requires dict's __getitem__ to call __missing__. It doesn't say anything about get(). Should get() call __missing__? If it does, things like defaultdict.get() might break. It will however be more consistent with dict's specification. If it doesn't, we expect Mapping to not care about __missing__ as it's only a dict thing, which will require UserDict to override get(). Dict's get() will need to receive a doc update as well stating __missing__ is not called. Second question is: Is __missing__ only a dict thing, or is it part of the Mapping ABC? I would expect it to be a part of the Mapping ABC, with subclasses not having to implement it. Right now it's not. Looking forward for your inputs, Bar Harel